38 using ExecutionSpace =
typename DeviceType::execution_space;
39 using ScratchSpace =
typename ExecutionSpace::scratch_memory_space;
40 using OutputScratchView = Kokkos::View<OutputScalar*,ScratchSpace,Kokkos::MemoryTraits<Kokkos::Unmanaged>>;
41 using PointScratchView = Kokkos::View<PointScalar*, ScratchSpace,Kokkos::MemoryTraits<Kokkos::Unmanaged>>;
43 using TeamPolicy = Kokkos::TeamPolicy<ExecutionSpace>;
44 using TeamMember =
typename TeamPolicy::member_type;
48 OutputFieldType output_;
49 InputPointsType inputPoints_;
52 bool defineVertexFunctions_;
53 int numFields_, numPoints_;
55 size_t fad_size_output_;
57 static const int numVertices = 3;
58 static const int numEdges = 3;
59 const int edge_start_[numEdges] = {0,1,0};
60 const int edge_end_[numEdges] = {1,2,2};
63 int polyOrder,
bool defineVertexFunctions)
64 : opType_(opType), output_(output), inputPoints_(inputPoints),
65 polyOrder_(polyOrder), defineVertexFunctions_(defineVertexFunctions),
68 numFields_ = output.extent_int(0);
69 numPoints_ = output.extent_int(1);
70 INTREPID2_TEST_FOR_EXCEPTION(numPoints_ != inputPoints.extent_int(0), std::invalid_argument,
"point counts need to match!");
71 INTREPID2_TEST_FOR_EXCEPTION(numFields_ != (polyOrder_+1)*(polyOrder_+2)/2, std::invalid_argument,
"output field size does not match basis cardinality");
74 KOKKOS_INLINE_FUNCTION
75 void operator()(
const TeamMember & teamMember )
const
77 auto pointOrdinal = teamMember.league_rank();
78 OutputScratchView edge_field_values_at_point, jacobi_values_at_point, other_values_at_point, other_values2_at_point;
79 if (fad_size_output_ > 0) {
80 edge_field_values_at_point = OutputScratchView(teamMember.team_shmem(), polyOrder_ + 1, fad_size_output_);
81 jacobi_values_at_point = OutputScratchView(teamMember.team_shmem(), polyOrder_ + 1, fad_size_output_);
82 other_values_at_point = OutputScratchView(teamMember.team_shmem(), polyOrder_ + 1, fad_size_output_);
83 other_values2_at_point = OutputScratchView(teamMember.team_shmem(), polyOrder_ + 1, fad_size_output_);
86 edge_field_values_at_point = OutputScratchView(teamMember.team_shmem(), polyOrder_ + 1);
87 jacobi_values_at_point = OutputScratchView(teamMember.team_shmem(), polyOrder_ + 1);
88 other_values_at_point = OutputScratchView(teamMember.team_shmem(), polyOrder_ + 1);
89 other_values2_at_point = OutputScratchView(teamMember.team_shmem(), polyOrder_ + 1);
92 const auto & x = inputPoints_(pointOrdinal,0);
93 const auto & y = inputPoints_(pointOrdinal,1);
96 const PointScalar lambda[3] = {1. - x - y, x, y};
97 const PointScalar lambda_dx[3] = {-1., 1., 0.};
98 const PointScalar lambda_dy[3] = {-1., 0., 1.};
100 const int num1DEdgeFunctions = polyOrder_ - 1;
107 for (
int vertexOrdinal=0; vertexOrdinal<numVertices; vertexOrdinal++)
109 output_(vertexOrdinal,pointOrdinal) = lambda[vertexOrdinal];
111 if (!defineVertexFunctions_)
115 output_(0,pointOrdinal) = 1.0;
119 int fieldOrdinalOffset = 3;
120 for (
int edgeOrdinal=0; edgeOrdinal<numEdges; edgeOrdinal++)
122 const auto & s0 = lambda[edge_start_[edgeOrdinal]];
123 const auto & s1 = lambda[ edge_end_[edgeOrdinal]];
125 Polynomials::shiftedScaledIntegratedLegendreValues(edge_field_values_at_point, polyOrder_, PointScalar(s1), PointScalar(s0+s1));
126 for (
int edgeFunctionOrdinal=0; edgeFunctionOrdinal<num1DEdgeFunctions; edgeFunctionOrdinal++)
129 output_(edgeFunctionOrdinal+fieldOrdinalOffset,pointOrdinal) = edge_field_values_at_point(edgeFunctionOrdinal+2);
131 fieldOrdinalOffset += num1DEdgeFunctions;
137 const double jacobiScaling = 1.0;
139 const int max_ij_sum = polyOrder_;
142 const int min_ij_sum = min_i + min_j;
143 for (
int ij_sum = min_ij_sum; ij_sum <= max_ij_sum; ij_sum++)
145 for (
int i=min_i; i<=ij_sum-min_j; i++)
147 const int j = ij_sum - i;
148 const int edgeBasisOrdinal = i+numVertices-2;
149 const auto & edgeValue = output_(edgeBasisOrdinal,pointOrdinal);
150 const double alpha = i*2.0;
152 Polynomials::shiftedScaledIntegratedJacobiValues(jacobi_values_at_point, alpha, polyOrder_-2, lambda[2], jacobiScaling);
153 const auto & jacobiValue = jacobi_values_at_point(j);
154 output_(fieldOrdinalOffset,pointOrdinal) = edgeValue * jacobiValue;
155 fieldOrdinalOffset++;
165 if (defineVertexFunctions_)
169 output_(0,pointOrdinal,0) = -1.0;
170 output_(0,pointOrdinal,1) = -1.0;
176 output_(0,pointOrdinal,0) = 0.0;
177 output_(0,pointOrdinal,1) = 0.0;
180 output_(1,pointOrdinal,0) = 1.0;
181 output_(1,pointOrdinal,1) = 0.0;
183 output_(2,pointOrdinal,0) = 0.0;
184 output_(2,pointOrdinal,1) = 1.0;
187 int fieldOrdinalOffset = 3;
199 auto & P_i_minus_1 = edge_field_values_at_point;
200 auto & L_i_dt = jacobi_values_at_point;
201 for (
int edgeOrdinal=0; edgeOrdinal<numEdges; edgeOrdinal++)
203 const auto & s0 = lambda[edge_start_[edgeOrdinal]];
204 const auto & s1 = lambda[ edge_end_[edgeOrdinal]];
206 const auto & s0_dx = lambda_dx[edge_start_[edgeOrdinal]];
207 const auto & s0_dy = lambda_dy[edge_start_[edgeOrdinal]];
208 const auto & s1_dx = lambda_dx[ edge_end_[edgeOrdinal]];
209 const auto & s1_dy = lambda_dy[ edge_end_[edgeOrdinal]];
211 Polynomials::shiftedScaledLegendreValues (P_i_minus_1, polyOrder_-1, PointScalar(s1), PointScalar(s0+s1));
212 Polynomials::shiftedScaledIntegratedLegendreValues_dt(L_i_dt, polyOrder_, PointScalar(s1), PointScalar(s0+s1));
213 for (
int edgeFunctionOrdinal=0; edgeFunctionOrdinal<num1DEdgeFunctions; edgeFunctionOrdinal++)
216 const int i = edgeFunctionOrdinal+2;
217 output_(edgeFunctionOrdinal+fieldOrdinalOffset,pointOrdinal,0) = P_i_minus_1(i-1) * s1_dx + L_i_dt(i) * (s1_dx + s0_dx);
218 output_(edgeFunctionOrdinal+fieldOrdinalOffset,pointOrdinal,1) = P_i_minus_1(i-1) * s1_dy + L_i_dt(i) * (s1_dy + s0_dy);
220 fieldOrdinalOffset += num1DEdgeFunctions;
241 auto & P_2i_j_minus_1 = edge_field_values_at_point;
242 auto & L_2i_j_dt = jacobi_values_at_point;
243 auto & L_i = other_values_at_point;
244 auto & L_2i_j = other_values2_at_point;
247 const double jacobiScaling = 1.0;
249 const int max_ij_sum = polyOrder_;
252 const int min_ij_sum = min_i + min_j;
253 for (
int ij_sum = min_ij_sum; ij_sum <= max_ij_sum; ij_sum++)
255 for (
int i=min_i; i<=ij_sum-min_j; i++)
257 const int j = ij_sum - i;
259 const int edgeBasisOrdinal = i+numVertices-2;
260 const auto & grad_L_i_dx = output_(edgeBasisOrdinal,pointOrdinal,0);
261 const auto & grad_L_i_dy = output_(edgeBasisOrdinal,pointOrdinal,1);
263 const double alpha = i*2.0;
265 Polynomials::shiftedScaledIntegratedLegendreValues (L_i, polyOrder_, lambda[1], lambda[0]+lambda[1]);
266 Polynomials::shiftedScaledIntegratedJacobiValues_dt(L_2i_j_dt, alpha, polyOrder_, lambda[2], jacobiScaling);
267 Polynomials::shiftedScaledIntegratedJacobiValues ( L_2i_j, alpha, polyOrder_, lambda[2], jacobiScaling);
268 Polynomials::shiftedScaledJacobiValues(P_2i_j_minus_1, alpha, polyOrder_-1, lambda[2], jacobiScaling);
270 const auto & s0_dx = lambda_dx[0];
271 const auto & s0_dy = lambda_dy[0];
272 const auto & s1_dx = lambda_dx[1];
273 const auto & s1_dy = lambda_dy[1];
274 const auto & s2_dx = lambda_dx[2];
275 const auto & s2_dy = lambda_dy[2];
277 const OutputScalar basisValue_dx = L_2i_j(j) * grad_L_i_dx + L_i(i) * (P_2i_j_minus_1(j-1) * s2_dx + L_2i_j_dt(j) * (s0_dx + s1_dx + s2_dx));
278 const OutputScalar basisValue_dy = L_2i_j(j) * grad_L_i_dy + L_i(i) * (P_2i_j_minus_1(j-1) * s2_dy + L_2i_j_dt(j) * (s0_dy + s1_dy + s2_dy));
280 output_(fieldOrdinalOffset,pointOrdinal,0) = basisValue_dx;
281 output_(fieldOrdinalOffset,pointOrdinal,1) = basisValue_dy;
282 fieldOrdinalOffset++;
297 INTREPID2_TEST_FOR_ABORT(
true,
298 ">>> ERROR: (Intrepid2::Basis_HGRAD_TRI_Cn_FEM_ORTH::OrthPolynomialTri) Computing of second and higher-order derivatives is not currently supported");
308 size_t team_shmem_size (
int team_size)
const
311 size_t shmem_size = 0;
312 if (fad_size_output_ > 0)
313 shmem_size += 4 * OutputScratchView::shmem_size(polyOrder_ + 1, fad_size_output_);
315 shmem_size += 4 * OutputScratchView::shmem_size(polyOrder_ + 1);