39 using ExecutionSpace =
typename DeviceType::execution_space;
40 using ScratchSpace =
typename ExecutionSpace::scratch_memory_space;
41 using OutputScratchView = Kokkos::View<OutputScalar*,ScratchSpace,Kokkos::MemoryTraits<Kokkos::Unmanaged>>;
42 using PointScratchView = Kokkos::View<PointScalar*, ScratchSpace,Kokkos::MemoryTraits<Kokkos::Unmanaged>>;
44 using TeamPolicy = Kokkos::TeamPolicy<ExecutionSpace>;
45 using TeamMember =
typename TeamPolicy::member_type;
49 OutputFieldType output_;
50 InputPointsType inputPoints_;
52 ordinal_type polyOrder_;
53 ordinal_type numFields_, numPoints_;
55 size_t fad_size_output_;
57 static constexpr ordinal_type numVertices = 4;
58 static constexpr ordinal_type numEdges = 6;
59 static constexpr ordinal_type numEdgesPerFace = 3;
60 static constexpr ordinal_type numFaceFamilies = 2;
61 static constexpr ordinal_type numFaces = 4;
62 static constexpr ordinal_type numVerticesPerFace = 3;
63 static constexpr ordinal_type numInteriorFamilies = 3;
66 const ordinal_type face_vertices[numFaces*numVerticesPerFace] = {0,1,2,
75 const ordinal_type face_edges[numFaces * numEdgesPerFace] = {0,1,2,
81 const ordinal_type edge_start_[numEdges] = {0,1,0,0,1,2};
82 const ordinal_type edge_end_[numEdges] = {1,2,2,3,3,3};
83 const ordinal_type face_family_start_ [numFaceFamilies] = {0,1};
84 const ordinal_type face_family_middle_[numFaceFamilies] = {1,2};
85 const ordinal_type face_family_end_ [numFaceFamilies] = {2,0};
87 const ordinal_type numEdgeFunctions_;
88 const ordinal_type numFaceFunctionsPerFace_;
89 const ordinal_type numFaceFunctions_;
90 const ordinal_type numInteriorFunctionsPerFamily_;
91 const ordinal_type numInteriorFunctions_;
94 const ordinal_type faceOrdinalForInterior_[numInteriorFamilies] = {0,2,3};
95 const ordinal_type faceFamilyForInterior_[numInteriorFamilies] = {0,0,1};
96 const ordinal_type interiorCoordinateOrdinal_[numInteriorFamilies] = {3,0,1};
98 KOKKOS_INLINE_FUNCTION
99 ordinal_type dofOrdinalForFace(
const ordinal_type &faceOrdinal,
100 const ordinal_type &zeroBasedFaceFamily,
101 const ordinal_type &i,
102 const ordinal_type &j)
const
105 const ordinal_type faceDofOffset = numEdgeFunctions_ + faceOrdinal * numFaceFunctionsPerFace_;
111 const ordinal_type max_ij_sum = polyOrder_ - 1;
113 ordinal_type fieldOrdinal = faceDofOffset + zeroBasedFaceFamily;
115 for (ordinal_type ij_sum=1; ij_sum <= max_ij_sum; ij_sum++)
117 for (ordinal_type ii=0; ii<ij_sum; ii++)
120 const ordinal_type jj = ij_sum - ii;
121 if ( (ii == i) && (jj == j))
126 fieldOrdinal += numFaceFamilies;
133 : opType_(opType), output_(output), inputPoints_(inputPoints),
134 polyOrder_(polyOrder),
136 numEdgeFunctions_(polyOrder * numEdges),
137 numFaceFunctionsPerFace_(polyOrder * (polyOrder-1)),
138 numFaceFunctions_(numFaceFunctionsPerFace_*numFaces),
139 numInteriorFunctionsPerFamily_((polyOrder > 2) ? (polyOrder-2)*(polyOrder-1)*polyOrder/6 : 0),
140 numInteriorFunctions_(numInteriorFunctionsPerFamily_ * numInteriorFamilies)
142 numFields_ = output.extent_int(0);
143 numPoints_ = output.extent_int(1);
145 const ordinal_type expectedCardinality = numEdgeFunctions_ + numFaceFunctions_ + numInteriorFunctions_;
151 INTREPID2_TEST_FOR_EXCEPTION(numPoints_ != inputPoints.extent_int(0), std::invalid_argument,
"point counts need to match!");
152 INTREPID2_TEST_FOR_EXCEPTION(numFields_ != expectedCardinality, std::invalid_argument,
"output field size does not match basis cardinality");
155 KOKKOS_INLINE_FUNCTION
156 void computeEdgeLegendre(OutputScratchView &P,
157 const ordinal_type &edgeOrdinal,
158 const PointScalar* lambda)
const
160 const auto & s0 = lambda[edge_start_[edgeOrdinal]];
161 const auto & s1 = lambda[ edge_end_[edgeOrdinal]];
163 Polynomials::shiftedScaledLegendreValues(P, polyOrder_-1, PointScalar(s1), PointScalar(s0+s1));
166 KOKKOS_INLINE_FUNCTION
167 void edgeFunctionValue(OutputScalar &edgeValue_x,
168 OutputScalar &edgeValue_y,
169 OutputScalar &edgeValue_z,
170 const ordinal_type &edgeOrdinal,
171 OutputScratchView &P,
172 const ordinal_type &i,
173 const PointScalar* lambda,
174 const PointScalar* lambda_dx,
175 const PointScalar* lambda_dy,
176 const PointScalar* lambda_dz
179 const auto & s0 = lambda [edge_start_[edgeOrdinal]];
180 const auto & s0_dx = lambda_dx[edge_start_[edgeOrdinal]];
181 const auto & s0_dy = lambda_dy[edge_start_[edgeOrdinal]];
182 const auto & s0_dz = lambda_dz[edge_start_[edgeOrdinal]];
184 const auto & s1 = lambda [ edge_end_[edgeOrdinal]];
185 const auto & s1_dx = lambda_dx[ edge_end_[edgeOrdinal]];
186 const auto & s1_dy = lambda_dy[ edge_end_[edgeOrdinal]];
187 const auto & s1_dz = lambda_dz[ edge_end_[edgeOrdinal]];
189 const auto & P_i = P(i);
190 const PointScalar xWeight = s0 * s1_dx - s1 * s0_dx;
191 const PointScalar yWeight = s0 * s1_dy - s1 * s0_dy;
192 const PointScalar zWeight = s0 * s1_dz - s1 * s0_dz;
193 edgeValue_x = P_i * xWeight;
194 edgeValue_y = P_i * yWeight;
195 edgeValue_z = P_i * zWeight;
198 KOKKOS_INLINE_FUNCTION
199 void computeFaceIntegratedJacobi(OutputScratchView &L_2ip1,
200 const ordinal_type &zeroBasedFaceOrdinal,
201 const ordinal_type &zeroBasedFamilyOrdinal,
202 const ordinal_type &i,
203 const PointScalar* lambda)
const
205 const auto &s0_vertex_number = face_family_start_ [zeroBasedFamilyOrdinal];
206 const auto &s1_vertex_number = face_family_middle_[zeroBasedFamilyOrdinal];
207 const auto &s2_vertex_number = face_family_end_ [zeroBasedFamilyOrdinal];
210 const auto &s0_index = face_vertices[zeroBasedFaceOrdinal * numVerticesPerFace + s0_vertex_number];
211 const auto &s1_index = face_vertices[zeroBasedFaceOrdinal * numVerticesPerFace + s1_vertex_number];
212 const auto &s2_index = face_vertices[zeroBasedFaceOrdinal * numVerticesPerFace + s2_vertex_number];
214 const auto & s0 = lambda[s0_index];
215 const auto & s1 = lambda[s1_index];
216 const auto & s2 = lambda[s2_index];
217 const PointScalar jacobiScaling = s0 + s1 + s2;
219 const double alpha = i*2.0 + 1;
220 Polynomials::shiftedScaledIntegratedJacobiValues(L_2ip1, alpha, polyOrder_-1, s2, jacobiScaling);
223 KOKKOS_INLINE_FUNCTION
224 void faceFunctionValue(OutputScalar &value_x,
225 OutputScalar &value_y,
226 OutputScalar &value_z,
227 const ordinal_type &j,
228 const OutputScratchView &L_2ip1,
229 const OutputScalar &edgeValue_x,
230 const OutputScalar &edgeValue_y,
231 const OutputScalar &edgeValue_z,
232 const PointScalar* lambda)
const
234 const auto & L_2ip1_j = L_2ip1(j);
235 value_x = edgeValue_x * L_2ip1_j;
236 value_y = edgeValue_y * L_2ip1_j;
237 value_z = edgeValue_z * L_2ip1_j;
240 KOKKOS_INLINE_FUNCTION
241 void operator()(
const TeamMember & teamMember )
const
243 const ordinal_type numFunctionsPerFace = polyOrder_ * (polyOrder_ - 1);
244 auto pointOrdinal = teamMember.league_rank();
245 OutputScratchView edge_field_values_at_point, jacobi_values_at_point, other_values_at_point, other_values2_at_point;
246 if (fad_size_output_ > 0) {
247 edge_field_values_at_point = OutputScratchView(teamMember.team_shmem(), polyOrder_, fad_size_output_);
248 jacobi_values_at_point = OutputScratchView(teamMember.team_shmem(), polyOrder_, fad_size_output_);
249 other_values_at_point = OutputScratchView(teamMember.team_shmem(), polyOrder_, fad_size_output_);
250 other_values2_at_point = OutputScratchView(teamMember.team_shmem(), polyOrder_, fad_size_output_);
253 edge_field_values_at_point = OutputScratchView(teamMember.team_shmem(), polyOrder_);
254 jacobi_values_at_point = OutputScratchView(teamMember.team_shmem(), polyOrder_);
255 other_values_at_point = OutputScratchView(teamMember.team_shmem(), polyOrder_);
256 other_values2_at_point = OutputScratchView(teamMember.team_shmem(), polyOrder_);
259 const auto & x = inputPoints_(pointOrdinal,0);
260 const auto & y = inputPoints_(pointOrdinal,1);
261 const auto & z = inputPoints_(pointOrdinal,2);
264 const PointScalar lambda[4] = {1. - x - y - z, x, y, z};
265 const PointScalar lambda_dx[4] = {-1., 1., 0., 0.};
266 const PointScalar lambda_dy[4] = {-1., 0., 1., 0.};
267 const PointScalar lambda_dz[4] = {-1., 0., 0., 1.};
269 const int num1DEdgeFunctions = polyOrder_;
278 auto & P = edge_field_values_at_point;
280 int fieldOrdinalOffset = 0;
281 for (
int edgeOrdinal=0; edgeOrdinal<numEdges; edgeOrdinal++)
283 computeEdgeLegendre(P, edgeOrdinal, lambda);
285 for (
int i=0; i<num1DEdgeFunctions; i++)
287 auto &output_x = output_(i+fieldOrdinalOffset,pointOrdinal,0);
288 auto &output_y = output_(i+fieldOrdinalOffset,pointOrdinal,1);
289 auto &output_z = output_(i+fieldOrdinalOffset,pointOrdinal,2);
291 edgeFunctionValue(output_x, output_y, output_z,
293 lambda, lambda_dx, lambda_dy, lambda_dz);
295 fieldOrdinalOffset += num1DEdgeFunctions;
301 auto & L_2ip1 = jacobi_values_at_point;
304 const int max_ij_sum = polyOrder_ - 1;
307 int faceFieldOrdinalOffset = fieldOrdinalOffset;
308 for (
int faceOrdinal = 0; faceOrdinal < numFaces; faceOrdinal++) {
309 for (
int familyOrdinal=1; familyOrdinal<=numFaceFamilies; familyOrdinal++)
311 int fieldOrdinal = faceFieldOrdinalOffset + familyOrdinal - 1;
313 for (
int ij_sum=1; ij_sum <= max_ij_sum; ij_sum++)
315 for (
int i=0; i<ij_sum; i++)
317 computeFaceIntegratedJacobi(L_2ip1, faceOrdinal, familyOrdinal-1, i, lambda);
319 const int j = ij_sum - i;
321 const int faceEdgeOrdinal = familyOrdinal-1;
322 const int volumeEdgeOrdinal = face_edges[faceOrdinal * numEdgesPerFace + faceEdgeOrdinal];
323 const int edgeBasisOrdinal = i + volumeEdgeOrdinal*num1DEdgeFunctions;
324 const auto & edgeValue_x = output_(edgeBasisOrdinal,pointOrdinal,0);
325 const auto & edgeValue_y = output_(edgeBasisOrdinal,pointOrdinal,1);
326 const auto & edgeValue_z = output_(edgeBasisOrdinal,pointOrdinal,2);
328 auto & output_x = output_(fieldOrdinal,pointOrdinal,0);
329 auto & output_y = output_(fieldOrdinal,pointOrdinal,1);
330 auto & output_z = output_(fieldOrdinal,pointOrdinal,2);
332 faceFunctionValue(output_x, output_y, output_z, j, L_2ip1, edgeValue_x, edgeValue_y, edgeValue_z, lambda);
334 fieldOrdinal += numFaceFamilies;
337 fieldOrdinalOffset = fieldOrdinal - numFaceFamilies + 1;
339 faceFieldOrdinalOffset += numFunctionsPerFace;
345 const int interiorFieldOrdinalOffset = fieldOrdinalOffset;
346 const int min_ijk_sum = 2;
347 const int max_ijk_sum = polyOrder_-1;
350 const auto & L_2ipj = jacobi_values_at_point;
351 for (
int interiorFamilyOrdinal=1; interiorFamilyOrdinal<=numInteriorFamilies; interiorFamilyOrdinal++)
356 const auto & lambda_m = lambda[interiorCoordinateOrdinal_[interiorFamilyOrdinal-1]];
357 const PointScalar jacobiScaling = 1.0;
359 ordinal_type fieldOrdinal = interiorFieldOrdinalOffset + interiorFamilyOrdinal - 1;
361 const ordinal_type relatedFaceOrdinal = faceOrdinalForInterior_[interiorFamilyOrdinal-1];
362 const ordinal_type relatedFaceFamily = faceFamilyForInterior_ [interiorFamilyOrdinal-1];
364 for (
int ijk_sum=min_ijk_sum; ijk_sum <= max_ijk_sum; ijk_sum++)
366 for (
int i=0; i<ijk_sum-1; i++)
368 for (
int j=1; j<ijk_sum-i; j++)
371 const ordinal_type faceDofOrdinal = dofOrdinalForFace(relatedFaceOrdinal, relatedFaceFamily, i, j);
373 const double alpha = 2 * (i + j);
375 Polynomials::shiftedScaledIntegratedJacobiValues(L_2ipj, alpha, polyOrder_-1, lambda_m, jacobiScaling);
377 const int k = ijk_sum - i - j;
378 const auto & L_k = L_2ipj(k);
379 for (
int d=0; d<3; d++)
381 const auto & E_face_d = output_(faceDofOrdinal,pointOrdinal,d);
382 output_(fieldOrdinal,pointOrdinal,d) = L_k * E_face_d;
384 fieldOrdinal += numInteriorFamilies;
388 fieldOrdinalOffset = fieldOrdinal - numInteriorFamilies + 1;
397 int fieldOrdinalOffset = 0;
404 auto & P_i = edge_field_values_at_point;
405 auto & L_2ip1_j = jacobi_values_at_point;
406 for (
int edgeOrdinal=0; edgeOrdinal<numEdges; edgeOrdinal++)
408 const auto & s0 = lambda[edge_start_[edgeOrdinal]];
409 const auto & s1 = lambda[ edge_end_[edgeOrdinal]];
411 const auto & s0_dx = lambda_dx[edge_start_[edgeOrdinal]];
412 const auto & s0_dy = lambda_dy[edge_start_[edgeOrdinal]];
413 const auto & s0_dz = lambda_dz[edge_start_[edgeOrdinal]];
414 const auto & s1_dx = lambda_dx[ edge_end_[edgeOrdinal]];
415 const auto & s1_dy = lambda_dy[ edge_end_[edgeOrdinal]];
416 const auto & s1_dz = lambda_dz[ edge_end_[edgeOrdinal]];
418 const OutputScalar grad_s0_cross_grad_s1[3] = {s0_dy * s1_dz - s0_dz * s1_dy,
419 s0_dz * s1_dx - s0_dx * s1_dz,
420 s0_dx * s1_dy - s0_dy * s1_dx};
422 Polynomials::shiftedScaledLegendreValues(P_i, polyOrder_-1, PointScalar(s1), PointScalar(s0+s1));
423 for (
int i=0; i<num1DEdgeFunctions; i++)
425 for (
int d=0; d<3; d++)
427 output_(i+fieldOrdinalOffset,pointOrdinal,d) = (i+2) * P_i(i) * grad_s0_cross_grad_s1[d];
430 fieldOrdinalOffset += num1DEdgeFunctions;
451 auto & P_2ip1_j = other_values_at_point;
452 auto & L_2ip1_j_dt = other_values2_at_point;
455 int faceFieldOrdinalOffset = fieldOrdinalOffset;
456 for (
int faceOrdinal=0; faceOrdinal<numFaces; faceOrdinal++)
458 for (
int familyOrdinal=1; familyOrdinal<=numFaceFamilies; familyOrdinal++)
460 int fieldOrdinal = faceFieldOrdinalOffset + familyOrdinal - 1;
462 const auto &s0_vertex_number = face_family_start_ [familyOrdinal-1];
463 const auto &s1_vertex_number = face_family_middle_[familyOrdinal-1];
464 const auto &s2_vertex_number = face_family_end_ [familyOrdinal-1];
467 const auto &s0_index = face_vertices[faceOrdinal * numVerticesPerFace + s0_vertex_number];
468 const auto &s1_index = face_vertices[faceOrdinal * numVerticesPerFace + s1_vertex_number];
469 const auto &s2_index = face_vertices[faceOrdinal * numVerticesPerFace + s2_vertex_number];
471 const auto & s0 = lambda[s0_index];
472 const auto & s1 = lambda[s1_index];
473 const auto & s2 = lambda[s2_index];
474 const PointScalar jacobiScaling = s0 + s1 + s2;
476 const auto & s0_dx = lambda_dx[s0_index];
477 const auto & s0_dy = lambda_dy[s0_index];
478 const auto & s0_dz = lambda_dz[s0_index];
479 const auto & s1_dx = lambda_dx[s1_index];
480 const auto & s1_dy = lambda_dy[s1_index];
481 const auto & s1_dz = lambda_dz[s1_index];
482 const auto & s2_dx = lambda_dx[s2_index];
483 const auto & s2_dy = lambda_dy[s2_index];
484 const auto & s2_dz = lambda_dz[s2_index];
486 const PointScalar grad_s2[3] = {s2_dx, s2_dy, s2_dz};
487 const PointScalar gradJacobiScaling[3] = {s0_dx + s1_dx + s2_dx,
488 s0_dy + s1_dy + s2_dy,
489 s0_dz + s1_dz + s2_dz};
491 const PointScalar grad_s0_cross_grad_s1[3] = {s0_dy * s1_dz - s0_dz * s1_dy,
492 s0_dz * s1_dx - s0_dx * s1_dz,
493 s0_dx * s1_dy - s0_dy * s1_dx};
495 const PointScalar s0_grad_s1_minus_s1_grad_s0[3] = {s0 * s1_dx - s1 * s0_dx,
496 s0 * s1_dy - s1 * s0_dy,
497 s0 * s1_dz - s1 * s0_dz};
499 Polynomials::shiftedScaledLegendreValues (P_i, polyOrder_-1, PointScalar(s1), PointScalar(s0+s1));
506 const int max_ij_sum = polyOrder_ - 1;
507 for (
int ij_sum=1; ij_sum <= max_ij_sum; ij_sum++)
509 for (
int i=0; i<ij_sum; i++)
511 const int j = ij_sum - i;
513 const double alpha = i*2.0 + 1;
515 Polynomials::shiftedScaledJacobiValues (P_2ip1_j, alpha, polyOrder_-1, PointScalar(s2), jacobiScaling);
516 Polynomials::shiftedScaledIntegratedJacobiValues (L_2ip1_j, alpha, polyOrder_-1, PointScalar(s2), jacobiScaling);
517 Polynomials::shiftedScaledIntegratedJacobiValues_dt(L_2ip1_j_dt, alpha, polyOrder_-1, PointScalar(s2), jacobiScaling);
519 const PointScalar & edgeValue = P_i(i);
521 PointScalar grad_L_2ip1_j[3];
522 for (
int d=0; d<3; d++)
524 grad_L_2ip1_j[d] = P_2ip1_j(j-1) * grad_s2[d]
525 + L_2ip1_j_dt(j) * gradJacobiScaling[d];
528 const PointScalar grad_L_2ip1_j_cross_E_i[3] = { grad_L_2ip1_j[1] * edgeValue * s0_grad_s1_minus_s1_grad_s0[2] - grad_L_2ip1_j[2] * edgeValue * s0_grad_s1_minus_s1_grad_s0[1],
529 grad_L_2ip1_j[2] * edgeValue * s0_grad_s1_minus_s1_grad_s0[0] - grad_L_2ip1_j[0] * edgeValue * s0_grad_s1_minus_s1_grad_s0[2],
530 grad_L_2ip1_j[0] * edgeValue * s0_grad_s1_minus_s1_grad_s0[1] - grad_L_2ip1_j[1] * edgeValue * s0_grad_s1_minus_s1_grad_s0[0] };
532 for (
int d=0; d<3; d++)
534 const OutputScalar edgeCurl_d = (i+2.) * P_i(i) * grad_s0_cross_grad_s1[d];
535 output_(fieldOrdinal,pointOrdinal,d) = L_2ip1_j(j) * edgeCurl_d
536 + grad_L_2ip1_j_cross_E_i[d];
539 fieldOrdinal += numFaceFamilies;
542 fieldOrdinalOffset = fieldOrdinal - numFaceFamilies + 1;
544 faceFieldOrdinalOffset += numFunctionsPerFace;
550 auto & L_2ipj = jacobi_values_at_point;
551 auto & P_2ipj = other_values_at_point;
552 auto & L_2ip1 = edge_field_values_at_point;
553 auto & P = other_values2_at_point;
555 const int interiorFieldOrdinalOffset = fieldOrdinalOffset;
556 const int min_ijk_sum = 2;
557 const int max_ijk_sum = polyOrder_-1;
558 for (
int interiorFamilyOrdinal=1; interiorFamilyOrdinal<=numInteriorFamilies; interiorFamilyOrdinal++)
562 const ordinal_type relatedFaceOrdinal = faceOrdinalForInterior_[interiorFamilyOrdinal-1];
563 const ordinal_type relatedFaceFamily = faceFamilyForInterior_ [interiorFamilyOrdinal-1];
566 const auto & m = interiorCoordinateOrdinal_[interiorFamilyOrdinal-1];
567 const auto & lambda_m = lambda[m];
568 const PointScalar jacobiScaling = 1.0;
570 ordinal_type fieldOrdinal = interiorFieldOrdinalOffset + interiorFamilyOrdinal - 1;
572 for (
int ijk_sum=min_ijk_sum; ijk_sum <= max_ijk_sum; ijk_sum++)
574 for (
int i=0; i<ijk_sum-1; i++)
576 computeFaceIntegratedJacobi(L_2ip1, relatedFaceOrdinal, relatedFaceFamily, i, lambda);
578 const ordinal_type faceEdgeOrdinal = relatedFaceFamily;
579 const int volumeEdgeOrdinal = face_edges[relatedFaceOrdinal * numEdgesPerFace + faceEdgeOrdinal];
580 computeEdgeLegendre(P, volumeEdgeOrdinal, lambda);
582 OutputScalar edgeValue[3];
583 edgeFunctionValue(edgeValue[0], edgeValue[1], edgeValue[2], volumeEdgeOrdinal, P, i, lambda, lambda_dx, lambda_dy, lambda_dz);
585 for (
int j=1; j<ijk_sum-i; j++)
588 const ordinal_type faceDofOrdinal = dofOrdinalForFace(relatedFaceOrdinal, relatedFaceFamily, i, j);
590 const double alpha = 2 * (i + j);
592 Polynomials::shiftedScaledIntegratedJacobiValues(L_2ipj, alpha, polyOrder_-1, lambda_m, jacobiScaling);
593 Polynomials::shiftedScaledJacobiValues (P_2ipj, alpha, polyOrder_-1, lambda_m, jacobiScaling);
598 const int k = ijk_sum - i - j;
599 const auto & L_k = L_2ipj(k);
600 const auto & P_km1 = P_2ipj(k-1);
602 const PointScalar grad_L_k[3] = {P_km1 * lambda_dx[m],
603 P_km1 * lambda_dy[m],
604 P_km1 * lambda_dz[m]};
607 OutputScalar E_face[3];
608 faceFunctionValue(E_face[0], E_face[1], E_face[2], j, L_2ip1, edgeValue[0], edgeValue[1], edgeValue[2], lambda);
610 PointScalar grad_L_k_cross_E_face[3] = {grad_L_k[1] * E_face[2] - grad_L_k[2] * E_face[1],
611 grad_L_k[2] * E_face[0] - grad_L_k[0] * E_face[2],
612 grad_L_k[0] * E_face[1] - grad_L_k[1] * E_face[0]};
613 for (
int d=0; d<3; d++)
615 const auto & curl_E_face_d = output_(faceDofOrdinal,pointOrdinal,d);
616 output_(fieldOrdinal,pointOrdinal,d) = L_k * curl_E_face_d + grad_L_k_cross_E_face[d];
619 fieldOrdinal += numInteriorFamilies;
623 fieldOrdinalOffset = fieldOrdinal - numInteriorFamilies + 1;
639 INTREPID2_TEST_FOR_ABORT(
true,
640 ">>> ERROR: (Intrepid2::Hierarchical_HCURL_TET_Functor) Unsupported differential operator");
650 size_t team_shmem_size (
int team_size)
const
653 size_t shmem_size = 0;
654 if (fad_size_output_ > 0)
655 shmem_size += 4 * OutputScratchView::shmem_size(polyOrder_ + 1, fad_size_output_);
657 shmem_size += 4 * OutputScratchView::shmem_size(polyOrder_ + 1);