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 int numFields_, numPoints_;
54 size_t fad_size_output_;
56 static const int numVertices = 3;
57 static const int numEdges = 3;
58 static const int numFaceFamilies = 2;
59 const int edge_start_[numEdges] = {0,1,0};
60 const int edge_end_[numEdges] = {1,2,2};
61 const int face_family_start_[numFaceFamilies] = {0,1};
62 const int face_family_middle_[numFaceFamilies] = {1,2};
63 const int face_family_end_ [numFaceFamilies] = {2,0};
66 : opType_(opType), output_(output), inputPoints_(inputPoints),
67 polyOrder_(polyOrder),
70 numFields_ = output.extent_int(0);
71 numPoints_ = output.extent_int(1);
72 const int expectedCardinality = 3 * polyOrder_ + polyOrder_ * (polyOrder-1);
74 INTREPID2_TEST_FOR_EXCEPTION(numPoints_ != inputPoints.extent_int(0), std::invalid_argument,
"point counts need to match!");
75 INTREPID2_TEST_FOR_EXCEPTION(numFields_ != expectedCardinality, std::invalid_argument,
"output field size does not match basis cardinality");
78 KOKKOS_INLINE_FUNCTION
79 void operator()(
const TeamMember & teamMember )
const
81 auto pointOrdinal = teamMember.league_rank();
82 OutputScratchView edge_field_values_at_point, jacobi_values_at_point, other_values_at_point, other_values2_at_point;
83 if (fad_size_output_ > 0) {
84 edge_field_values_at_point = OutputScratchView(teamMember.team_shmem(), polyOrder_, fad_size_output_);
85 jacobi_values_at_point = OutputScratchView(teamMember.team_shmem(), polyOrder_, fad_size_output_);
86 other_values_at_point = OutputScratchView(teamMember.team_shmem(), polyOrder_, fad_size_output_);
87 other_values2_at_point = OutputScratchView(teamMember.team_shmem(), polyOrder_, fad_size_output_);
90 edge_field_values_at_point = OutputScratchView(teamMember.team_shmem(), polyOrder_);
91 jacobi_values_at_point = OutputScratchView(teamMember.team_shmem(), polyOrder_);
92 other_values_at_point = OutputScratchView(teamMember.team_shmem(), polyOrder_);
93 other_values2_at_point = OutputScratchView(teamMember.team_shmem(), polyOrder_);
96 const auto & x = inputPoints_(pointOrdinal,0);
97 const auto & y = inputPoints_(pointOrdinal,1);
100 const PointScalar lambda[3] = {1. - x - y, x, y};
101 const PointScalar lambda_dx[3] = {-1., 1., 0.};
102 const PointScalar lambda_dy[3] = {-1., 0., 1.};
104 const int num1DEdgeFunctions = polyOrder_;
111 int fieldOrdinalOffset = 0;
112 for (
int edgeOrdinal=0; edgeOrdinal<numEdges; edgeOrdinal++)
114 const auto & s0 = lambda [edge_start_[edgeOrdinal]];
115 const auto & s0_dx = lambda_dx[edge_start_[edgeOrdinal]];
116 const auto & s0_dy = lambda_dy[edge_start_[edgeOrdinal]];
118 const auto & s1 = lambda [ edge_end_[edgeOrdinal]];
119 const auto & s1_dx = lambda_dx[ edge_end_[edgeOrdinal]];
120 const auto & s1_dy = lambda_dy[ edge_end_[edgeOrdinal]];
122 Polynomials::shiftedScaledLegendreValues(edge_field_values_at_point, polyOrder_-1, PointScalar(s1), PointScalar(s0+s1));
123 for (
int edgeFunctionOrdinal=0; edgeFunctionOrdinal<num1DEdgeFunctions; edgeFunctionOrdinal++)
125 const auto & legendreValue = edge_field_values_at_point(edgeFunctionOrdinal);
126 const PointScalar xWeight = s0 * s1_dx - s1 * s0_dx;
127 const PointScalar yWeight = s0 * s1_dy - s1 * s0_dy;
128 output_(edgeFunctionOrdinal+fieldOrdinalOffset,pointOrdinal,0) = legendreValue * xWeight;
129 output_(edgeFunctionOrdinal+fieldOrdinalOffset,pointOrdinal,1) = legendreValue * yWeight;
131 fieldOrdinalOffset += num1DEdgeFunctions;
137 const double jacobiScaling = 1.0;
139 const int max_ij_sum = polyOrder_ - 1;
142 const int faceFieldOrdinalOffset = fieldOrdinalOffset;
143 for (
int familyOrdinal=1; familyOrdinal<=2; familyOrdinal++)
145 int fieldOrdinal = faceFieldOrdinalOffset + familyOrdinal - 1;
146 const auto &s2 = lambda[ face_family_end_[familyOrdinal-1]];
147 for (
int ij_sum=1; ij_sum <= max_ij_sum; ij_sum++)
149 for (
int i=0; i<ij_sum; i++)
151 const int j = ij_sum - i;
153 const int edgeBasisOrdinal = i + (familyOrdinal-1)*num1DEdgeFunctions;
154 const auto & edgeValue_x = output_(edgeBasisOrdinal,pointOrdinal,0);
155 const auto & edgeValue_y = output_(edgeBasisOrdinal,pointOrdinal,1);
156 const double alpha = i*2.0 + 1;
158 Polynomials::shiftedScaledIntegratedJacobiValues(jacobi_values_at_point, alpha, polyOrder_-1, s2, jacobiScaling);
159 const auto & jacobiValue = jacobi_values_at_point(j);
160 output_(fieldOrdinal,pointOrdinal,0) = edgeValue_x * jacobiValue;
161 output_(fieldOrdinal,pointOrdinal,1) = edgeValue_y * jacobiValue;
173 int fieldOrdinalOffset = 0;
180 auto & P_i = edge_field_values_at_point;
181 auto & L_2ip1_j = jacobi_values_at_point;
182 for (
int edgeOrdinal=0; edgeOrdinal<numEdges; edgeOrdinal++)
184 const auto & s0 = lambda[edge_start_[edgeOrdinal]];
185 const auto & s1 = lambda[ edge_end_[edgeOrdinal]];
187 const auto & s0_dx = lambda_dx[edge_start_[edgeOrdinal]];
188 const auto & s0_dy = lambda_dy[edge_start_[edgeOrdinal]];
189 const auto & s1_dx = lambda_dx[ edge_end_[edgeOrdinal]];
190 const auto & s1_dy = lambda_dy[ edge_end_[edgeOrdinal]];
192 const OutputScalar grad_s0_cross_grad_s1 = s0_dx * s1_dy - s1_dx * s0_dy;
194 Polynomials::shiftedScaledLegendreValues(P_i, polyOrder_-1, PointScalar(s1), PointScalar(s0+s1));
195 for (
int i=0; i<num1DEdgeFunctions; i++)
197 output_(i+fieldOrdinalOffset,pointOrdinal) = (i+2) * P_i(i) * grad_s0_cross_grad_s1;
199 fieldOrdinalOffset += num1DEdgeFunctions;
220 auto & P_2ip1_j = other_values_at_point;
223 const int faceFieldOrdinalOffset = fieldOrdinalOffset;
224 for (
int familyOrdinal=1; familyOrdinal<=2; familyOrdinal++)
226 int fieldOrdinal = faceFieldOrdinalOffset + familyOrdinal - 1;
228 const auto &s0_index = face_family_start_ [familyOrdinal-1];
229 const auto &s1_index = face_family_middle_[familyOrdinal-1];
230 const auto &s2_index = face_family_end_ [familyOrdinal-1];
231 const auto &s0 = lambda[s0_index];
232 const auto &s1 = lambda[s1_index];
233 const auto &s2 = lambda[s2_index];
234 const double jacobiScaling = 1.0;
236 const auto & s0_dx = lambda_dx[s0_index];
237 const auto & s0_dy = lambda_dy[s0_index];
238 const auto & s1_dx = lambda_dx[s1_index];
239 const auto & s1_dy = lambda_dy[s1_index];
240 const auto & s2_dx = lambda_dx[s2_index];
241 const auto & s2_dy = lambda_dy[s2_index];
243 const OutputScalar grad_s0_cross_grad_s1 = s0_dx * s1_dy - s1_dx * s0_dy;
245 Polynomials::shiftedScaledLegendreValues (P_i, polyOrder_-1, PointScalar(s1), PointScalar(s0+s1));
249 const PointScalar xEdgeWeight = s0 * s1_dx - s1 * s0_dx;
250 const PointScalar yEdgeWeight = s0 * s1_dy - s1 * s0_dy;
251 OutputScalar grad_s2_cross_xy_edgeWeight = s2_dx * yEdgeWeight - xEdgeWeight * s2_dy;
253 const int max_ij_sum = polyOrder_ - 1;
254 for (
int ij_sum=1; ij_sum <= max_ij_sum; ij_sum++)
256 for (
int i=0; i<ij_sum; i++)
258 const int j = ij_sum - i;
259 const OutputScalar edgeCurl = (i+2.) * P_i(i) * grad_s0_cross_grad_s1;
261 const double alpha = i*2.0 + 1;
263 Polynomials::shiftedScaledJacobiValues(P_2ip1_j, alpha, polyOrder_-1, PointScalar(s2), jacobiScaling);
264 Polynomials::shiftedScaledIntegratedJacobiValues(L_2ip1_j, alpha, polyOrder_-1, s2, jacobiScaling);
266 const PointScalar & edgeValue = P_i(i);
267 output_(fieldOrdinal,pointOrdinal) = L_2ip1_j(j) * edgeCurl + P_2ip1_j(j-1) * edgeValue * grad_s2_cross_xy_edgeWeight;
286 INTREPID2_TEST_FOR_ABORT(
true,
287 ">>> ERROR: (Intrepid2::Hierarchical_HCURL_TRI_Functor) Unsupported differential operator");
297 size_t team_shmem_size (
int team_size)
const
300 size_t shmem_size = 0;
301 if (fad_size_output_ > 0)
302 shmem_size += 4 * OutputScratchView::shmem_size(polyOrder_ + 1, fad_size_output_);
304 shmem_size += 4 * OutputScratchView::shmem_size(polyOrder_ + 1);