9 #ifndef _COMPADRE_BASIS_HPP_
10 #define _COMPADRE_BASIS_HPP_
32 template <
typename BasisData>
33 KOKKOS_INLINE_FUNCTION
34 void calcPij(
const BasisData& data,
const member_type& teamMember,
double* delta,
double* thread_workspace,
const int target_index,
int neighbor_index,
const double alpha,
const int dimension,
const int poly_order,
bool specific_order_only =
false,
const scratch_matrix_right_type* V = NULL,
const ReconstructionSpace reconstruction_space =
ReconstructionSpace::ScalarTaylorPolynomial,
const SamplingFunctional polynomial_sampling_functional =
PointSample,
const int evaluation_site_local_index = 0) {
39 const int my_num_neighbors = data._pc._nla.getNumberOfNeighborsDevice(target_index);
42 const double factorial[15] = {1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880, 3628800, 39916800, 479001600, 6227020800, 87178291200};
45 if (neighbor_index >= my_num_neighbors) {
46 component = neighbor_index / my_num_neighbors;
47 neighbor_index = neighbor_index % my_num_neighbors;
48 }
else if (neighbor_index < 0) {
52 component = -(neighbor_index+1);
56 if (neighbor_index > -1) {
58 for (
int i=0; i<dimension; ++i) {
60 relative_coord[i] = (alpha-1)*data._pc.getTargetCoordinate(target_index, i, V);
61 relative_coord[i] += (1-alpha)*data._pc.getNeighborCoordinate(target_index, neighbor_index, i, V);
63 }
else if (evaluation_site_local_index > 0) {
65 for (
int i=0; i<dimension; ++i) {
68 relative_coord[i] = data._additional_pc.getNeighborCoordinate(target_index, evaluation_site_local_index-1, i, V);
69 relative_coord[i] -= data._pc.getTargetCoordinate(target_index, i, V);
73 for (
int i=0; i<3; ++i) relative_coord[i] = 0;
77 if ((polynomial_sampling_functional ==
PointSample ||
83 double cutoff_p = data._epsilons(target_index);
84 const int start_index = specific_order_only ? poly_order : 0;
94 const int dimension_offset =
GMLS::getNP(data._poly_order, dimension, reconstruction_space);
95 double cutoff_p = data._epsilons(target_index);
96 const int start_index = specific_order_only ? poly_order : 0;
98 for (
int d=0;
d<dimension; ++
d) {
100 ScalarTaylorPolynomialBasis::evaluate(teamMember, delta+component*dimension_offset, thread_workspace, dimension, poly_order, cutoff_p, relative_coord.
x, relative_coord.
y, relative_coord.
z, start_index);
102 for (
int n=0; n<dimension_offset; ++n) {
103 *(delta+
d*dimension_offset+n) = 0;
110 double cutoff_p = data._epsilons(target_index);
115 double cutoff_p = data._epsilons(target_index);
121 double cutoff_p = data._epsilons(target_index);
122 const int start_index = specific_order_only ? poly_order : 0;
124 ScalarTaylorPolynomialBasis::evaluate(teamMember, delta, thread_workspace, dimension, poly_order, cutoff_p, relative_coord.
x, relative_coord.
y, relative_coord.
z, start_index, 0.0, -1.0);
125 relative_coord.
x = 0;
126 relative_coord.
y = 0;
127 relative_coord.
z = 0;
128 ScalarTaylorPolynomialBasis::evaluate(teamMember, delta, thread_workspace, dimension, poly_order, cutoff_p, relative_coord.
x, relative_coord.
y, relative_coord.
z, start_index, 1.0, 1.0);
130 Kokkos::single(Kokkos::PerThread(teamMember), [&] () {
132 double cutoff_p = data._epsilons(target_index);
135 const int start_index = specific_order_only ? poly_order : 0;
137 for (
int quadrature = 0; quadrature<data._qm.getNumberOfQuadraturePoints(); ++quadrature) {
141 XYZ tangent_quadrature_coord_2d;
142 XYZ quadrature_coord_2d;
143 for (
int j=0; j<dimension; ++j) {
145 quadrature_coord_2d[j] = (data._qm.getSite(quadrature,0)-1)*data._pc.getTargetCoordinate(target_index, j, V);
146 quadrature_coord_2d[j] += (1-data._qm.getSite(quadrature,0))*data._pc.getNeighborCoordinate(target_index, neighbor_index, j, V);
147 tangent_quadrature_coord_2d[j] = data._pc.getTargetCoordinate(target_index, j, V);
148 tangent_quadrature_coord_2d[j] -= data._pc.getNeighborCoordinate(target_index, neighbor_index, j, V);
150 for (
int j=0; j<data._basis_multiplier; ++j) {
151 for (
int n = start_index; n <= poly_order; n++){
152 for (alphay = 0; alphay <= n; alphay++){
154 alphaf = factorial[alphax]*factorial[alphay];
158 v0 = (j==0) ? std::pow(quadrature_coord_2d.
x/cutoff_p,alphax)
159 *std::pow(quadrature_coord_2d.
y/cutoff_p,alphay)/alphaf : 0;
160 v1 = (j==0) ? 0 : std::pow(quadrature_coord_2d.
x/cutoff_p,alphax)
161 *std::pow(quadrature_coord_2d.
y/cutoff_p,alphay)/alphaf;
163 double dot_product = tangent_quadrature_coord_2d[0]*v0 + tangent_quadrature_coord_2d[1]*v1;
167 *(delta+i) = dot_product * data._qm.getWeight(quadrature);
169 *(delta+i) += dot_product * data._qm.getWeight(quadrature);
178 double cutoff_p = data._epsilons(target_index);
179 int alphax, alphay, alphaz;
181 const int start_index = specific_order_only ? poly_order : 0;
183 for (
int quadrature = 0; quadrature<data._qm.getNumberOfQuadraturePoints(); ++quadrature) {
187 XYZ quadrature_coord_3d;
188 XYZ tangent_quadrature_coord_3d;
189 for (
int j=0; j<dimension; ++j) {
191 quadrature_coord_3d[j] = (data._qm.getSite(quadrature,0)-1)*data._pc.getTargetCoordinate(target_index, j, NULL);
192 quadrature_coord_3d[j] += (1-data._qm.getSite(quadrature,0))*data._pc.getNeighborCoordinate(target_index, neighbor_index, j, NULL);
193 tangent_quadrature_coord_3d[j] = data._pc.getTargetCoordinate(target_index, j, NULL);
194 tangent_quadrature_coord_3d[j] -= data._pc.getNeighborCoordinate(target_index, neighbor_index, j, NULL);
196 for (
int j=0; j<data._basis_multiplier; ++j) {
197 for (
int n = start_index; n <= poly_order; n++) {
198 if (dimension == 3) {
199 for (alphaz = 0; alphaz <= n; alphaz++){
201 for (alphay = 0; alphay <= s; alphay++){
203 alphaf = factorial[alphax]*factorial[alphay]*factorial[alphaz];
210 v1 = std::pow(quadrature_coord_3d.
x/cutoff_p,alphax)
211 *std::pow(quadrature_coord_3d.
y/cutoff_p,alphay)
212 *std::pow(quadrature_coord_3d.
z/cutoff_p,alphaz)/alphaf;
218 v2 = std::pow(quadrature_coord_3d.
x/cutoff_p,alphax)
219 *std::pow(quadrature_coord_3d.
y/cutoff_p,alphay)
220 *std::pow(quadrature_coord_3d.
z/cutoff_p,alphaz)/alphaf;
223 v0 = std::pow(quadrature_coord_3d.
x/cutoff_p,alphax)
224 *std::pow(quadrature_coord_3d.
y/cutoff_p,alphay)
225 *std::pow(quadrature_coord_3d.
z/cutoff_p,alphaz)/alphaf;
231 double dot_product = tangent_quadrature_coord_3d[0]*v0 + tangent_quadrature_coord_3d[1]*v1 + tangent_quadrature_coord_3d[2]*v2;
234 if (quadrature == 0) {
235 *(delta+i) = dot_product * data._qm.getWeight(quadrature);
237 *(delta+i) += dot_product * data._qm.getWeight(quadrature);
242 }
else if (dimension == 2) {
243 for (alphay = 0; alphay <= n; alphay++){
245 alphaf = factorial[alphax]*factorial[alphay];
252 v1 = std::pow(quadrature_coord_3d.
x/cutoff_p,alphax)
253 *std::pow(quadrature_coord_3d.
y/cutoff_p,alphay)/alphaf;
256 v0 = std::pow(quadrature_coord_3d.
x/cutoff_p,alphax)
257 *std::pow(quadrature_coord_3d.
y/cutoff_p,alphay)/alphaf;
262 double dot_product = tangent_quadrature_coord_3d[0]*v0 + tangent_quadrature_coord_3d[1]*v1;
265 if (quadrature == 0) {
266 *(delta+i) = dot_product * data._qm.getWeight(quadrature);
268 *(delta+i) += dot_product * data._qm.getWeight(quadrature);
285 "FaceNormalIntegralSample, EdgeTangentIntegralSample, FaceNormalAverageSample, \
286 and EdgeTangentAverageSample only support 2d or 3d with 2d manifold");
289 &&
"Only 1d quadrature may be specified for edge integrals");
292 &&
"Quadrature points not generated");
297 "Sampling functional does not support specific_order_only");
299 double cutoff_p = data._epsilons(target_index);
300 auto global_neighbor_index = data._pc.getNeighborIndex(target_index, neighbor_index);
311 int quadrature_point_loop = data._qm.getNumberOfQuadraturePoints();
314 double G_data[3*TWO];
315 double edge_coords[3*TWO];
316 for (
int i=0; i<data._global_dimensions*TWO; ++i) G_data[i] = 0;
317 for (
int i=0; i<data._global_dimensions*TWO; ++i) edge_coords[i] = 0;
328 for (
int j=0; j<data._global_dimensions; ++j) {
329 edge_coords_matrix(j, 0) = data._source_extra_data(global_neighbor_index, j);
330 edge_coords_matrix(j, 1) = data._source_extra_data(global_neighbor_index, data._global_dimensions + j) - edge_coords_matrix(j, 0);
331 radius += edge_coords_matrix(j, 0)*edge_coords_matrix(j, 0);
333 radius = std::sqrt(radius);
337 auto E = edge_coords_matrix;
342 XYZ a = {E(0,0), E(1,0), E(2,0)};
343 XYZ b = {E(0,1)+E(0,0), E(1,1)+E(1,0), E(2,1)+E(2,0)};
344 double a_dot_b = a[0]*b[0] + a[1]*b[1] + a[2]*b[2];
346 theta = std::atan(norm_a_cross_b / a_dot_b);
350 double entire_edge_length = 0.0;
351 for (
int quadrature = 0; quadrature<quadrature_point_loop; ++quadrature) {
353 double G_determinant = 1.0;
354 double scaled_transformed_qp[3] = {0,0,0};
355 double unscaled_transformed_qp[3] = {0,0,0};
356 for (
int j=0; j<data._global_dimensions; ++j) {
357 unscaled_transformed_qp[j] += E(j,1)*data._qm.getSite(quadrature, 0);
359 unscaled_transformed_qp[j] += E(j,0);
368 double transformed_qp_norm = 0;
369 for (
int j=0; j<data._global_dimensions; ++j) {
370 transformed_qp_norm += unscaled_transformed_qp[j]*unscaled_transformed_qp[j];
372 transformed_qp_norm = std::sqrt(transformed_qp_norm);
374 for (
int j=0; j<data._global_dimensions; ++j) {
375 scaled_transformed_qp[j] = unscaled_transformed_qp[j] * radius / transformed_qp_norm;
378 G_determinant = radius * theta;
379 XYZ qp = XYZ(scaled_transformed_qp[0], scaled_transformed_qp[1], scaled_transformed_qp[2]);
380 for (
int j=0; j<data._local_dimensions; ++j) {
381 relative_coord[j] = data._pc.convertGlobalToLocalCoordinate(qp,j,*V)
382 - data._pc.getTargetCoordinate(target_index,j,V);
385 relative_coord[2] = 0;
387 XYZ endpoints_difference = {E(0,1), E(1,1), 0};
388 G_determinant = data._pc.EuclideanVectorLength(endpoints_difference, 2);
389 for (
int j=0; j<data._local_dimensions; ++j) {
390 relative_coord[j] = unscaled_transformed_qp[j]
391 - data._pc.getTargetCoordinate(target_index,j,V);
394 relative_coord[2] = 0;
401 for (
int j=0; j<data._global_dimensions; ++j) {
403 direction[j] = data._source_extra_data(global_neighbor_index, 2*data._global_dimensions + j);
408 XYZ k = {scaled_transformed_qp[0], scaled_transformed_qp[1], scaled_transformed_qp[2]};
409 double k_norm = std::sqrt(k[0]*k[0]+k[1]*k[1]+k[2]*k[2]);
410 k[0] = k[0]/k_norm; k[1] = k[1]/k_norm; k[2] = k[2]/k_norm;
411 XYZ n = {data._source_extra_data(global_neighbor_index, 2*data._global_dimensions + 0),
412 data._source_extra_data(global_neighbor_index, 2*data._global_dimensions + 1),
413 data._source_extra_data(global_neighbor_index, 2*data._global_dimensions + 2)};
416 direction[0] = (k[1]*n[2] - k[2]*n[1]) / norm_k_cross_n;
417 direction[1] = (k[2]*n[0] - k[0]*n[2]) / norm_k_cross_n;
418 direction[2] = (k[0]*n[1] - k[1]*n[0]) / norm_k_cross_n;
420 for (
int j=0; j<data._global_dimensions; ++j) {
422 direction[j] = data._source_extra_data(global_neighbor_index, 3*data._global_dimensions + j);
430 for (
int j=0; j<data._basis_multiplier; ++j) {
434 local_direction[j] = data._pc.convertGlobalToLocalCoordinate(direction,j,*V);
439 for (
int j=0; j<data._basis_multiplier; ++j) {
440 for (
int n = 0; n <= poly_order; n++){
441 for (alphay = 0; alphay <= n; alphay++){
443 alphaf = factorial[alphax]*factorial[alphay];
447 v0 = (j==0) ? std::pow(relative_coord.x/cutoff_p,alphax)
448 *std::pow(relative_coord.y/cutoff_p,alphay)/alphaf : 0;
449 v1 = (j==1) ? std::pow(relative_coord.x/cutoff_p,alphax)
450 *std::pow(relative_coord.y/cutoff_p,alphay)/alphaf : 0;
453 double dot_product = 0.0;
456 dot_product = local_direction[0]*v0 + local_direction[1]*v1;
458 dot_product = direction[0]*v0 + direction[1]*v1;
463 *(delta+i) = dot_product * data._qm.getWeight(quadrature) * G_determinant;
465 *(delta+i) += dot_product * data._qm.getWeight(quadrature) * G_determinant;
471 entire_edge_length += G_determinant * data._qm.getWeight(quadrature);
476 for (
int j=0; j<data._basis_multiplier; ++j) {
477 for (
int n = 0; n <= poly_order; n++){
478 for (alphay = 0; alphay <= n; alphay++){
479 *(delta+k) /= entire_edge_length;
489 "CellAverageSample only supports 2d or 3d with 2d manifold");
490 auto global_neighbor_index = data._pc.getNeighborIndex(target_index, neighbor_index);
491 double cutoff_p = data._epsilons(target_index);
496 double triangle_coords[3*3];
497 for (
int i=0; i<data._global_dimensions*3; ++i) G_data[i] = 0;
498 for (
int i=0; i<data._global_dimensions*3; ++i) triangle_coords[i] = 0;
509 for (
int j=0; j<data._global_dimensions; ++j) {
511 triangle_coords_matrix(j, 0) = data._pc.getNeighborCoordinate(target_index, neighbor_index, j);
512 radius += triangle_coords_matrix(j, 0)*triangle_coords_matrix(j, 0);
514 radius = std::sqrt(radius);
518 int num_vertices = 0;
519 for (
int j=0; j<data._source_extra_data.extent_int(1); ++j) {
520 auto val = data._source_extra_data(global_neighbor_index, j);
527 num_vertices = num_vertices / data._global_dimensions;
528 auto T = triangle_coords_matrix;
532 double entire_cell_area = 0.0;
533 for (
int v=0; v<num_vertices; ++v) {
535 int v2 = (v+1) % num_vertices;
537 for (
int j=0; j<data._global_dimensions; ++j) {
538 triangle_coords_matrix(j,1) = data._source_extra_data(global_neighbor_index,
539 v1*data._global_dimensions+j)
540 - triangle_coords_matrix(j,0);
541 triangle_coords_matrix(j,2) = data._source_extra_data(global_neighbor_index,
542 v2*data._global_dimensions+j)
543 - triangle_coords_matrix(j,0);
550 for (
int quadrature = 0; quadrature<data._qm.getNumberOfQuadraturePoints(); ++quadrature) {
551 double unscaled_transformed_qp[3] = {0,0,0};
552 double scaled_transformed_qp[3] = {0,0,0};
553 for (
int j=0; j<data._global_dimensions; ++j) {
554 for (
int k=1; k<3; ++k) {
557 unscaled_transformed_qp[j] += T(j,k)*data._qm.getSite(quadrature, k-1);
560 unscaled_transformed_qp[j] += T(j,0);
564 double G_determinant = 1.0;
570 double transformed_qp_norm = 0;
571 for (
int j=0; j<data._global_dimensions; ++j) {
572 transformed_qp_norm += unscaled_transformed_qp[j]*unscaled_transformed_qp[j];
574 transformed_qp_norm = std::sqrt(transformed_qp_norm);
576 for (
int j=0; j<data._global_dimensions; ++j) {
577 scaled_transformed_qp[j] = unscaled_transformed_qp[j] * radius / transformed_qp_norm;
598 double qp_norm_sq = transformed_qp_norm*transformed_qp_norm;
599 for (
int j=0; j<data._global_dimensions; ++j) {
600 G(j,1) = T(j,1)/transformed_qp_norm;
601 G(j,2) = T(j,2)/transformed_qp_norm;
602 for (
int k=0; k<data._global_dimensions; ++k) {
603 G(j,1) += unscaled_transformed_qp[j]*(-0.5)*std::pow(qp_norm_sq,-1.5)
604 *2*(unscaled_transformed_qp[k]*T(k,1));
605 G(j,2) += unscaled_transformed_qp[j]*(-0.5)*std::pow(qp_norm_sq,-1.5)
606 *2*(unscaled_transformed_qp[k]*T(k,2));
610 Kokkos::subview(G, Kokkos::ALL(), 1), Kokkos::subview(G, Kokkos::ALL(), 2));
611 G_determinant *= radius*radius;
612 XYZ qp = XYZ(scaled_transformed_qp[0], scaled_transformed_qp[1], scaled_transformed_qp[2]);
613 for (
int j=0; j<data._local_dimensions; ++j) {
614 relative_coord[j] = data._pc.convertGlobalToLocalCoordinate(qp,j,*V)
615 - data._pc.getTargetCoordinate(target_index,j,V);
618 relative_coord[2] = 0;
621 Kokkos::subview(T, Kokkos::ALL(), 1), Kokkos::subview(T, Kokkos::ALL(), 2));
622 for (
int j=0; j<data._local_dimensions; ++j) {
623 relative_coord[j] = unscaled_transformed_qp[j]
624 - data._pc.getTargetCoordinate(target_index,j,V);
627 relative_coord[2] = 0;
632 "CellAverageSample does not support specific_order_only");
633 for (
int n = 0; n <= poly_order; n++){
634 for (alphay = 0; alphay <= n; alphay++){
636 alphaf = factorial[alphax]*factorial[alphay];
637 double val_to_sum = G_determinant * (data._qm.getWeight(quadrature)
638 * std::pow(relative_coord.x/cutoff_p,alphax)
639 * std::pow(relative_coord.y/cutoff_p,alphay) / alphaf);
640 if (quadrature==0 && v==0) *(delta+k) = val_to_sum;
641 else *(delta+k) += val_to_sum;
645 entire_cell_area += G_determinant * data._qm.getWeight(quadrature);
650 for (
int n = 0; n <= poly_order; n++){
651 for (alphay = 0; alphay <= n; alphay++){
652 *(delta+k) /= entire_cell_area;
679 template <
typename BasisData>
680 KOKKOS_INLINE_FUNCTION
681 void calcGradientPij(
const BasisData& data,
const member_type& teamMember,
double* delta,
double* thread_workspace,
const int target_index,
int neighbor_index,
const double alpha,
const int partial_direction,
const int dimension,
const int poly_order,
bool specific_order_only,
const scratch_matrix_right_type* V,
const ReconstructionSpace reconstruction_space,
const SamplingFunctional polynomial_sampling_functional,
const int evaluation_site_local_index = 0) {
687 const int my_num_neighbors = data._pc._nla.getNumberOfNeighborsDevice(target_index);
690 if (neighbor_index >= my_num_neighbors) {
691 component = neighbor_index / my_num_neighbors;
692 neighbor_index = neighbor_index % my_num_neighbors;
693 }
else if (neighbor_index < 0) {
697 component = -(neighbor_index+1);
705 if (neighbor_index > -1) {
706 for (
int i=0; i<dimension; ++i) {
708 relative_coord[i] = (alpha-1)*data._pc.getTargetCoordinate(target_index, i, V);
709 relative_coord[i] += (1-alpha)*data._pc.getNeighborCoordinate(target_index, neighbor_index, i, V);
711 }
else if (evaluation_site_local_index > 0) {
712 for (
int i=0; i<dimension; ++i) {
715 relative_coord[i] = data._additional_pc.getNeighborCoordinate(target_index, evaluation_site_local_index-1, i, V);
716 relative_coord[i] -= data._pc.getTargetCoordinate(target_index, i, V);
719 for (
int i=0; i<3; ++i) relative_coord[i] = 0;
722 double cutoff_p = data._epsilons(target_index);
723 const int start_index = specific_order_only ? poly_order : 0;
725 if ((polynomial_sampling_functional ==
PointSample ||
731 ScalarTaylorPolynomialBasis::evaluatePartialDerivative(teamMember, delta, thread_workspace, dimension, poly_order, partial_direction, cutoff_p, relative_coord.
x, relative_coord.
y, relative_coord.
z, start_index);
737 DivergenceFreePolynomialBasis::evaluatePartialDerivative(teamMember, delta, thread_workspace, dimension, poly_order, component, partial_direction, cutoff_p, relative_coord.
x, relative_coord.
y, relative_coord.
z);
742 BernsteinPolynomialBasis::evaluatePartialDerivative(teamMember, delta, thread_workspace, dimension, poly_order, component, partial_direction, cutoff_p, relative_coord.
x, relative_coord.
y, relative_coord.
z);
767 template <
typename BasisData>
768 KOKKOS_INLINE_FUNCTION
769 void calcHessianPij(
const BasisData& data,
const member_type& teamMember,
double* delta,
double* thread_workspace,
const int target_index,
int neighbor_index,
const double alpha,
const int partial_direction_1,
const int partial_direction_2,
const int dimension,
const int poly_order,
bool specific_order_only,
const scratch_matrix_right_type* V,
const ReconstructionSpace reconstruction_space,
const SamplingFunctional polynomial_sampling_functional,
const int evaluation_site_local_index = 0) {
775 const int my_num_neighbors = data._pc._nla.getNumberOfNeighborsDevice(target_index);
778 if (neighbor_index >= my_num_neighbors) {
779 component = neighbor_index / my_num_neighbors;
780 neighbor_index = neighbor_index % my_num_neighbors;
781 }
else if (neighbor_index < 0) {
785 component = -(neighbor_index+1);
793 if (neighbor_index > -1) {
794 for (
int i=0; i<dimension; ++i) {
796 relative_coord[i] = (alpha-1)*data._pc.getTargetCoordinate(target_index, i, V);
797 relative_coord[i] += (1-alpha)*data._pc.getNeighborCoordinate(target_index, neighbor_index, i, V);
799 }
else if (evaluation_site_local_index > 0) {
800 for (
int i=0; i<dimension; ++i) {
803 relative_coord[i] = data._additional_pc.getNeighborCoordinate(target_index, evaluation_site_local_index-1, i, V);
804 relative_coord[i] -= data._pc.getTargetCoordinate(target_index, i, V);
807 for (
int i=0; i<3; ++i) relative_coord[i] = 0;
810 double cutoff_p = data._epsilons(target_index);
812 if ((polynomial_sampling_functional ==
PointSample ||
818 ScalarTaylorPolynomialBasis::evaluateSecondPartialDerivative(teamMember, delta, thread_workspace, dimension, poly_order, partial_direction_1, partial_direction_2, cutoff_p, relative_coord.
x, relative_coord.
y, relative_coord.
z);
823 DivergenceFreePolynomialBasis::evaluateSecondPartialDerivative(teamMember, delta, thread_workspace, dimension, poly_order, component, partial_direction_1, partial_direction_2, cutoff_p, relative_coord.
x, relative_coord.
y, relative_coord.
z);
827 BernsteinPolynomialBasis::evaluateSecondPartialDerivative(teamMember, delta, thread_workspace, dimension, poly_order, component, partial_direction_1, partial_direction_2, cutoff_p, relative_coord.
x, relative_coord.
y, relative_coord.
z);
848 template <
typename BasisData>
849 KOKKOS_INLINE_FUNCTION
850 void createWeightsAndP(
const BasisData& data,
const member_type& teamMember,
scratch_vector_type delta,
scratch_vector_type thread_workspace,
scratch_matrix_right_type P,
scratch_vector_type w,
const int dimension,
int polynomial_order,
bool weight_p =
false,
scratch_matrix_right_type* V = NULL,
const ReconstructionSpace reconstruction_space =
ReconstructionSpace::ScalarTaylorPolynomial,
const SamplingFunctional polynomial_sampling_functional =
PointSample) {
854 const int target_index = data._initial_index_for_batch + teamMember.league_rank();
863 int my_num_neighbors = data._pc._nla.getNumberOfNeighborsDevice(target_index);
866 int storage_size = GMLS::getNP(polynomial_order, dimension, reconstruction_space);
867 storage_size *= data._basis_multiplier;
868 for (
int j = 0; j < delta.extent_int(0); ++j) {
871 for (
int j = 0; j < thread_workspace.extent_int(0); ++j) {
872 thread_workspace(j) = 0;
874 Kokkos::parallel_for(Kokkos::TeamThreadRange(teamMember,data._pc._nla.getNumberOfNeighborsDevice(target_index)),
877 for (
int d=0;
d<data._sampling_multiplier; ++
d) {
884 double alpha_weight = 1;
892 r = data._pc.EuclideanVectorLength(data._pc.getRelativeCoord(target_index, i, dimension) * alpha_weight, dimension);
894 r = data._pc.EuclideanVectorLength(data._pc.getRelativeCoord(target_index, i, dimension, V) * alpha_weight, dimension);
898 w(i+my_num_neighbors*
d) = GMLS::Wab(r, data._epsilons(target_index), data._weighting_type, data._weighting_p, data._weighting_n);
900 calcPij<BasisData>(data, teamMember, delta.data(), thread_workspace.data(), target_index, i + d*my_num_neighbors, 0 , dimension, polynomial_order,
false , V, reconstruction_space, polynomial_sampling_functional);
903 for (
int j = 0; j < storage_size; ++j) {
905 P(i+my_num_neighbors*d, j) = delta[j] * std::sqrt(w(i+my_num_neighbors*d));
910 for (
int j = 0; j < storage_size; ++j) {
912 P(i+my_num_neighbors*d, j) = delta[j];
919 teamMember.team_barrier();
945 template <
typename BasisData>
946 KOKKOS_INLINE_FUNCTION
954 const int target_index = data._initial_index_for_batch + teamMember.league_rank();
955 int storage_size = only_specific_order ? GMLS::getNP(1, dimension)-GMLS::getNP(0, dimension) : GMLS::getNP(data._curvature_poly_order, dimension);
956 for (
int j = 0; j < delta.extent_int(0); ++j) {
959 for (
int j = 0; j < thread_workspace.extent_int(0); ++j) {
960 thread_workspace(j) = 0;
962 Kokkos::parallel_for(Kokkos::TeamThreadRange(teamMember,data._pc._nla.getNumberOfNeighborsDevice(target_index)),
970 r = data._pc.EuclideanVectorLength(data._pc.getRelativeCoord(target_index, i, dimension), dimension);
972 r = data._pc.EuclideanVectorLength(data._pc.getRelativeCoord(target_index, i, dimension, V), dimension);
976 if (only_specific_order) {
977 w(i) = GMLS::Wab(r, data._epsilons(target_index), data._curvature_weighting_type, data._curvature_weighting_p, data._curvature_weighting_n);
978 calcPij<BasisData>(data, teamMember, delta.data(), thread_workspace.data(), target_index, i, 0 , dimension, 1,
true );
980 w(i) = GMLS::Wab(r, data._epsilons(target_index), data._curvature_weighting_type, data._curvature_weighting_p, data._curvature_weighting_n);
981 calcPij<BasisData>(data, teamMember, delta.data(), thread_workspace.data(), target_index, i, 0 , dimension, data._curvature_poly_order,
false , V);
984 for (
int j = 0; j < storage_size; ++j) {
985 P(i, j) = delta[j] * std::sqrt(w(i));
989 teamMember.team_barrier();
constexpr SamplingFunctional FaceNormalIntegralSample
For integrating polynomial dotted with normal over an edge.
constexpr SamplingFunctional EdgeTangentAverageSample
For polynomial dotted with tangent.
KOKKOS_INLINE_FUNCTION void evaluateSecondPartialDerivative(const member_type &teamMember, double *delta, double *workspace, const int dimension, const int max_degree, const int component, const int partial_direction_1, const int partial_direction_2, const double h, const double x, const double y, const double z, const int starting_order=0, const double weight_of_original_value=0.0, const double weight_of_new_value=1.0)
Evaluates the second partial derivatives of the Bernstein polynomial basis delta[j] = weight_of_origi...
ReconstructionSpace
Space in which to reconstruct polynomial.
Scalar basis reused as many times as there are components in the vector resulting in a much cheaper p...
#define compadre_kernel_assert_release(condition)
compadre_kernel_assert_release is similar to compadre_assert_release, but is a call on the device...
constexpr SamplingFunctional ManifoldVectorPointSample
Point evaluations of the entire vector source function (but on a manifold, so it includes a transform...
KOKKOS_INLINE_FUNCTION void evaluate(const member_type &teamMember, double *delta, double *workspace, const int dimension, const int max_degree, const int component, const double h, const double x, const double y, const double z, const int starting_order=0, const double weight_of_original_value=0.0, const double weight_of_new_value=1.0)
Evaluates the divergence-free polynomial basis delta[j] = weight_of_original_value * delta[j] + weigh...
team_policy::member_type member_type
#define compadre_kernel_assert_extreme_debug(condition)
constexpr SamplingFunctional VaryingManifoldVectorPointSample
For integrating polynomial dotted with normal over an edge.
KOKKOS_INLINE_FUNCTION double getAreaFromVectors(const member_type &teamMember, view_type_1 v1, view_type_2 v2)
KOKKOS_INLINE_FUNCTION void calcHessianPij(const BasisData &data, const member_type &teamMember, double *delta, double *thread_workspace, const int target_index, int neighbor_index, const double alpha, const int partial_direction_1, const int partial_direction_2, const int dimension, const int poly_order, bool specific_order_only, const scratch_matrix_right_type *V, const ReconstructionSpace reconstruction_space, const SamplingFunctional polynomial_sampling_functional, const int evaluation_site_local_index=0)
Evaluates the Hessian of a polynomial basis under the Dirac Delta (pointwise) sampling function...
KOKKOS_INLINE_FUNCTION void evaluate(const member_type &teamMember, double *delta, double *workspace, const int dimension, const int max_degree, const double h, const double x, const double y, const double z, const int starting_order=0, const double weight_of_original_value=0.0, const double weight_of_new_value=1.0)
Evaluates the scalar Taylor polynomial basis delta[j] = weight_of_original_value * delta[j] + weight_...
Vector polynomial basis having # of components _dimensions, or (_dimensions-1) in the case of manifol...
constexpr SamplingFunctional StaggeredEdgeAnalyticGradientIntegralSample
Analytical integral of a gradient source vector is just a difference of the scalar source at neighbor...
KOKKOS_INLINE_FUNCTION void calcGradientPij(const BasisData &data, const member_type &teamMember, double *delta, double *thread_workspace, const int target_index, int neighbor_index, const double alpha, const int partial_direction, const int dimension, const int poly_order, bool specific_order_only, const scratch_matrix_right_type *V, const ReconstructionSpace reconstruction_space, const SamplingFunctional polynomial_sampling_functional, const int evaluation_site_local_index=0)
Evaluates the gradient of a polynomial basis under the Dirac Delta (pointwise) sampling function...
Solve GMLS problem on a manifold (will use QR or SVD to solve the resultant GMLS problem dependent on...
static KOKKOS_INLINE_FUNCTION int getNP(const int m, const int dimension=3, const ReconstructionSpace r_space=ReconstructionSpace::ScalarTaylorPolynomial)
Returns size of the basis for a given polynomial order and dimension General to dimension 1...
constexpr SamplingFunctional StaggeredEdgeIntegralSample
Samples consist of the result of integrals of a vector dotted with the tangent along edges between ne...
Kokkos::View< double **, layout_right, Kokkos::MemoryTraits< Kokkos::Unmanaged > > scratch_matrix_right_type
Kokkos::View< double *, Kokkos::MemoryTraits< Kokkos::Unmanaged > > scratch_vector_type
Scalar polynomial basis centered at the target site and scaled by sum of basis powers e...
constexpr SamplingFunctional FaceNormalAverageSample
For polynomial dotted with normal on edge.
import subprocess import os import re import math import sys import argparse d d d
constexpr SamplingFunctional EdgeTangentIntegralSample
For integrating polynomial dotted with tangent over an edge.
KOKKOS_INLINE_FUNCTION void calcPij(const BasisData &data, const member_type &teamMember, double *delta, double *thread_workspace, const int target_index, int neighbor_index, const double alpha, const int dimension, const int poly_order, bool specific_order_only=false, const scratch_matrix_right_type *V=NULL, const ReconstructionSpace reconstruction_space=ReconstructionSpace::ScalarTaylorPolynomial, const SamplingFunctional polynomial_sampling_functional=PointSample, const int evaluation_site_local_index=0)
Evaluates the polynomial basis under a particular sampling function. Generally used to fill a row of ...
constexpr SamplingFunctional CellAverageSample
For polynomial integrated on cells.
KOKKOS_INLINE_FUNCTION void evaluatePartialDerivative(const member_type &teamMember, double *delta, double *workspace, const int dimension, const int max_degree, const int component, const int partial_direction, const double h, const double x, const double y, const double z, const int starting_order=0, const double weight_of_original_value=0.0, const double weight_of_new_value=1.0)
Evaluates the first partial derivatives of the Bernstein polynomial basis delta[j] = weight_of_origin...
KOKKOS_INLINE_FUNCTION void createWeightsAndP(const BasisData &data, const member_type &teamMember, scratch_vector_type delta, scratch_vector_type thread_workspace, scratch_matrix_right_type P, scratch_vector_type w, const int dimension, int polynomial_order, bool weight_p=false, scratch_matrix_right_type *V=NULL, const ReconstructionSpace reconstruction_space=ReconstructionSpace::ScalarTaylorPolynomial, const SamplingFunctional polynomial_sampling_functional=PointSample)
Fills the _P matrix with either P or P*sqrt(w)
Divergence-free vector polynomial basis.
KOKKOS_INLINE_FUNCTION void createWeightsAndPForCurvature(const BasisData &data, const member_type &teamMember, scratch_vector_type delta, scratch_vector_type thread_workspace, scratch_matrix_right_type P, scratch_vector_type w, const int dimension, bool only_specific_order, scratch_matrix_right_type *V=NULL)
Fills the _P matrix with P*sqrt(w) for use in solving for curvature.
KOKKOS_INLINE_FUNCTION void evaluate(const member_type &teamMember, double *delta, double *workspace, const int dimension, const int max_degree, const int component, const double h, const double x, const double y, const double z, const int starting_order=0, const double weight_of_original_value=0.0, const double weight_of_new_value=1.0)
Evaluates the Bernstein polynomial basis delta[j] = weight_of_original_value * delta[j] + weight_of_n...
constexpr SamplingFunctional PointSample
Available sampling functionals.
constexpr SamplingFunctional CellIntegralSample
For polynomial integrated on cells.
constexpr SamplingFunctional VectorPointSample
Point evaluations of the entire vector source function.
#define compadre_kernel_assert_debug(condition)
Bernstein polynomial basis.