49 #ifndef Intrepid2_IntegratedLegendreBasis_HGRAD_TET_h
50 #define Intrepid2_IntegratedLegendreBasis_HGRAD_TET_h
52 #include <Kokkos_View.hpp>
53 #include <Kokkos_DynRankView.hpp>
55 #include <Intrepid2_config.h>
67 template<
class ExecutionSpace,
class OutputScalar,
class PointScalar,
68 class OutputFieldType,
class InputPointsType>
71 using ScratchSpace =
typename ExecutionSpace::scratch_memory_space;
72 using OutputScratchView = Kokkos::View<OutputScalar*,ScratchSpace,Kokkos::MemoryTraits<Kokkos::Unmanaged>>;
73 using OutputScratchView2D = Kokkos::View<OutputScalar**,ScratchSpace,Kokkos::MemoryTraits<Kokkos::Unmanaged>>;
74 using PointScratchView = Kokkos::View<PointScalar*, ScratchSpace,Kokkos::MemoryTraits<Kokkos::Unmanaged>>;
76 using TeamPolicy = Kokkos::TeamPolicy<ExecutionSpace>;
77 using TeamMember =
typename TeamPolicy::member_type;
81 OutputFieldType output_;
82 InputPointsType inputPoints_;
85 bool defineVertexFunctions_;
86 int numFields_, numPoints_;
88 size_t fad_size_output_;
90 static const int numVertices = 4;
91 static const int numEdges = 6;
93 const int edge_start_[numEdges] = {0,1,0,0,1,2};
94 const int edge_end_[numEdges] = {1,2,2,3,3,3};
96 static const int numFaces = 4;
97 const int face_vertex_0[numFaces] = {0,0,1,0};
98 const int face_vertex_1[numFaces] = {1,1,2,2};
99 const int face_vertex_2[numFaces] = {2,3,3,3};
103 const int face_ordinal_of_first_edge[numFaces] = {0,0,1,2};
106 int polyOrder,
bool defineVertexFunctions)
107 : opType_(opType), output_(output), inputPoints_(inputPoints),
108 polyOrder_(polyOrder), defineVertexFunctions_(defineVertexFunctions),
111 numFields_ = output.extent_int(0);
112 numPoints_ = output.extent_int(1);
113 INTREPID2_TEST_FOR_EXCEPTION(numPoints_ != inputPoints.extent_int(0), std::invalid_argument,
"point counts need to match!");
114 INTREPID2_TEST_FOR_EXCEPTION(numFields_ != (polyOrder_+1)*(polyOrder_+2)*(polyOrder_+3)/6, std::invalid_argument,
"output field size does not match basis cardinality");
117 KOKKOS_INLINE_FUNCTION
118 void operator()(
const TeamMember & teamMember )
const
120 const int numFaceBasisFunctionsPerFace = (polyOrder_-2) * (polyOrder_-1) / 2;
121 const int numInteriorBasisFunctions = (polyOrder_-3) * (polyOrder_-2) * (polyOrder_-1) / 6;
123 auto pointOrdinal = teamMember.league_rank();
124 OutputScratchView legendre_values1_at_point, legendre_values2_at_point;
125 OutputScratchView2D jacobi_values1_at_point, jacobi_values2_at_point, jacobi_values3_at_point;
126 const int numAlphaValues = (polyOrder_-1 > 1) ? (polyOrder_-1) : 1;
127 if (fad_size_output_ > 0) {
128 legendre_values1_at_point = OutputScratchView(teamMember.team_shmem(), polyOrder_ + 1, fad_size_output_);
129 legendre_values2_at_point = OutputScratchView(teamMember.team_shmem(), polyOrder_ + 1, fad_size_output_);
130 jacobi_values1_at_point = OutputScratchView2D(teamMember.team_shmem(), numAlphaValues, polyOrder_ + 1, fad_size_output_);
131 jacobi_values2_at_point = OutputScratchView2D(teamMember.team_shmem(), numAlphaValues, polyOrder_ + 1, fad_size_output_);
132 jacobi_values3_at_point = OutputScratchView2D(teamMember.team_shmem(), numAlphaValues, polyOrder_ + 1, fad_size_output_);
135 legendre_values1_at_point = OutputScratchView(teamMember.team_shmem(), polyOrder_ + 1);
136 legendre_values2_at_point = OutputScratchView(teamMember.team_shmem(), polyOrder_ + 1);
137 jacobi_values1_at_point = OutputScratchView2D(teamMember.team_shmem(), numAlphaValues, polyOrder_ + 1);
138 jacobi_values2_at_point = OutputScratchView2D(teamMember.team_shmem(), numAlphaValues, polyOrder_ + 1);
139 jacobi_values3_at_point = OutputScratchView2D(teamMember.team_shmem(), numAlphaValues, polyOrder_ + 1);
142 const auto & x = inputPoints_(pointOrdinal,0);
143 const auto & y = inputPoints_(pointOrdinal,1);
144 const auto & z = inputPoints_(pointOrdinal,2);
147 const PointScalar lambda[numVertices] = {1. - x - y - z, x, y, z};
148 const PointScalar lambda_dx[numVertices] = {-1., 1., 0., 0.};
149 const PointScalar lambda_dy[numVertices] = {-1., 0., 1., 0.};
150 const PointScalar lambda_dz[numVertices] = {-1., 0., 0., 1.};
152 const int num1DEdgeFunctions = polyOrder_ - 1;
159 for (
int vertexOrdinal=0; vertexOrdinal<numVertices; vertexOrdinal++)
161 output_(vertexOrdinal,pointOrdinal) = lambda[vertexOrdinal];
163 if (!defineVertexFunctions_)
167 output_(0,pointOrdinal) = 1.0;
171 int fieldOrdinalOffset = numVertices;
172 for (
int edgeOrdinal=0; edgeOrdinal<numEdges; edgeOrdinal++)
174 const auto & s0 = lambda[edge_start_[edgeOrdinal]];
175 const auto & s1 = lambda[ edge_end_[edgeOrdinal]];
177 Polynomials::shiftedScaledIntegratedLegendreValues(legendre_values1_at_point, polyOrder_, PointScalar(s1), PointScalar(s0+s1));
178 for (
int edgeFunctionOrdinal=0; edgeFunctionOrdinal<num1DEdgeFunctions; edgeFunctionOrdinal++)
181 output_(edgeFunctionOrdinal+fieldOrdinalOffset,pointOrdinal) = legendre_values1_at_point(edgeFunctionOrdinal+2);
183 fieldOrdinalOffset += num1DEdgeFunctions;
189 for (
int faceOrdinal=0; faceOrdinal<numFaces; faceOrdinal++)
191 const auto & s0 = lambda[face_vertex_0[faceOrdinal]];
192 const auto & s1 = lambda[face_vertex_1[faceOrdinal]];
193 const auto & s2 = lambda[face_vertex_2[faceOrdinal]];
194 const PointScalar jacobiScaling = s0 + s1 + s2;
197 for (
int n=2; n<=polyOrder_; n++)
199 const double alpha = n*2;
200 const int alphaOrdinal = n-2;
201 using Kokkos::subview;
203 auto jacobi_alpha = subview(jacobi_values1_at_point, alphaOrdinal, ALL);
204 Polynomials::integratedJacobiValues(jacobi_alpha, alpha, polyOrder_-2, s2, jacobiScaling);
207 const int edgeOrdinal = face_ordinal_of_first_edge[faceOrdinal];
208 int localFaceBasisOrdinal = 0;
209 for (
int totalPolyOrder=3; totalPolyOrder<=polyOrder_; totalPolyOrder++)
211 for (
int i=2; i<totalPolyOrder; i++)
213 const int edgeBasisOrdinal = edgeOrdinal*num1DEdgeFunctions + i-2 + numVertices;
214 const auto & edgeValue = output_(edgeBasisOrdinal,pointOrdinal);
215 const int alphaOrdinal = i-2;
217 const int j = totalPolyOrder - i;
218 const auto & jacobiValue = jacobi_values1_at_point(alphaOrdinal,j);
219 const int fieldOrdinal = fieldOrdinalOffset + localFaceBasisOrdinal;
220 output_(fieldOrdinal,pointOrdinal) = edgeValue * jacobiValue;
222 localFaceBasisOrdinal++;
225 fieldOrdinalOffset += numFaceBasisFunctionsPerFace;
229 for (
int n=3; n<=polyOrder_; n++)
231 const double alpha = n*2;
232 const double jacobiScaling = 1.0;
233 const int alphaOrdinal = n-3;
234 using Kokkos::subview;
236 auto jacobi_alpha = subview(jacobi_values1_at_point, alphaOrdinal, ALL);
237 Polynomials::integratedJacobiValues(jacobi_alpha, alpha, polyOrder_-3, lambda[3], jacobiScaling);
242 const int min_ij = min_i + min_j;
243 const int min_ijk = min_ij + min_k;
244 int localInteriorBasisOrdinal = 0;
245 for (
int totalPolyOrder_ijk=min_ijk; totalPolyOrder_ijk <= polyOrder_; totalPolyOrder_ijk++)
247 int localFaceBasisOrdinal = 0;
248 for (
int totalPolyOrder_ij=min_ij; totalPolyOrder_ij <= totalPolyOrder_ijk-min_j; totalPolyOrder_ij++)
250 for (
int i=2; i <= totalPolyOrder_ij-min_j; i++)
252 const int j = totalPolyOrder_ij - i;
253 const int k = totalPolyOrder_ijk - totalPolyOrder_ij;
254 const int faceBasisOrdinal = numEdges*num1DEdgeFunctions + numVertices + localFaceBasisOrdinal;
255 const auto & faceValue = output_(faceBasisOrdinal,pointOrdinal);
256 const int alphaOrdinal = (i+j)-3;
257 localFaceBasisOrdinal++;
259 const int fieldOrdinal = fieldOrdinalOffset + localInteriorBasisOrdinal;
260 const auto & jacobiValue = jacobi_values1_at_point(alphaOrdinal,k);
261 output_(fieldOrdinal,pointOrdinal) = faceValue * jacobiValue;
262 localInteriorBasisOrdinal++;
266 fieldOrdinalOffset += numInteriorBasisFunctions;
273 if (defineVertexFunctions_)
277 output_(0,pointOrdinal,0) = -1.0;
278 output_(0,pointOrdinal,1) = -1.0;
279 output_(0,pointOrdinal,2) = -1.0;
285 output_(0,pointOrdinal,0) = 0.0;
286 output_(0,pointOrdinal,1) = 0.0;
287 output_(0,pointOrdinal,2) = 0.0;
290 output_(1,pointOrdinal,0) = 1.0;
291 output_(1,pointOrdinal,1) = 0.0;
292 output_(1,pointOrdinal,2) = 0.0;
294 output_(2,pointOrdinal,0) = 0.0;
295 output_(2,pointOrdinal,1) = 1.0;
296 output_(2,pointOrdinal,2) = 0.0;
298 output_(3,pointOrdinal,0) = 0.0;
299 output_(3,pointOrdinal,1) = 0.0;
300 output_(3,pointOrdinal,2) = 1.0;
303 int fieldOrdinalOffset = numVertices;
315 auto & P_i_minus_1 = legendre_values1_at_point;
316 auto & L_i_dt = legendre_values2_at_point;
317 for (
int edgeOrdinal=0; edgeOrdinal<numEdges; edgeOrdinal++)
319 const auto & s0 = lambda[edge_start_[edgeOrdinal]];
320 const auto & s1 = lambda[ edge_end_[edgeOrdinal]];
322 const auto & s0_dx = lambda_dx[edge_start_[edgeOrdinal]];
323 const auto & s0_dy = lambda_dy[edge_start_[edgeOrdinal]];
324 const auto & s0_dz = lambda_dz[edge_start_[edgeOrdinal]];
325 const auto & s1_dx = lambda_dx[ edge_end_[edgeOrdinal]];
326 const auto & s1_dy = lambda_dy[ edge_end_[edgeOrdinal]];
327 const auto & s1_dz = lambda_dz[ edge_end_[edgeOrdinal]];
329 Polynomials::shiftedScaledLegendreValues (P_i_minus_1, polyOrder_-1, PointScalar(s1), PointScalar(s0+s1));
330 Polynomials::shiftedScaledIntegratedLegendreValues_dt(L_i_dt, polyOrder_, PointScalar(s1), PointScalar(s0+s1));
331 for (
int edgeFunctionOrdinal=0; edgeFunctionOrdinal<num1DEdgeFunctions; edgeFunctionOrdinal++)
334 const int i = edgeFunctionOrdinal+2;
335 output_(edgeFunctionOrdinal+fieldOrdinalOffset,pointOrdinal,0) = P_i_minus_1(i-1) * s1_dx + L_i_dt(i) * (s1_dx + s0_dx);
336 output_(edgeFunctionOrdinal+fieldOrdinalOffset,pointOrdinal,1) = P_i_minus_1(i-1) * s1_dy + L_i_dt(i) * (s1_dy + s0_dy);
337 output_(edgeFunctionOrdinal+fieldOrdinalOffset,pointOrdinal,2) = P_i_minus_1(i-1) * s1_dz + L_i_dt(i) * (s1_dz + s0_dz);
339 fieldOrdinalOffset += num1DEdgeFunctions;
360 auto & L_i = legendre_values2_at_point;
361 auto & L_2i_j_dt = jacobi_values1_at_point;
362 auto & L_2i_j = jacobi_values2_at_point;
363 auto & P_2i_j_minus_1 = jacobi_values3_at_point;
365 for (
int faceOrdinal=0; faceOrdinal<numFaces; faceOrdinal++)
367 const auto & s0 = lambda[face_vertex_0[faceOrdinal]];
368 const auto & s1 = lambda[face_vertex_1[faceOrdinal]];
369 const auto & s2 = lambda[face_vertex_2[faceOrdinal]];
370 Polynomials::shiftedScaledIntegratedLegendreValues(L_i, polyOrder_, s1, s0+s1);
372 const PointScalar jacobiScaling = s0 + s1 + s2;
375 for (
int n=2; n<=polyOrder_; n++)
377 const double alpha = n*2;
378 const int alphaOrdinal = n-2;
379 using Kokkos::subview;
381 auto L_2i_j_dt_alpha = subview(L_2i_j_dt, alphaOrdinal, ALL);
382 auto L_2i_j_alpha = subview(L_2i_j, alphaOrdinal, ALL);
383 auto P_2i_j_minus_1_alpha = subview(P_2i_j_minus_1, alphaOrdinal, ALL);
384 Polynomials::integratedJacobiValues_dt(L_2i_j_dt_alpha, alpha, polyOrder_-2, s2, jacobiScaling);
385 Polynomials::integratedJacobiValues (L_2i_j_alpha, alpha, polyOrder_-2, s2, jacobiScaling);
386 Polynomials::shiftedScaledJacobiValues(P_2i_j_minus_1_alpha, alpha, polyOrder_-1, s2, jacobiScaling);
389 const int edgeOrdinal = face_ordinal_of_first_edge[faceOrdinal];
390 int localFaceOrdinal = 0;
391 for (
int totalPolyOrder=3; totalPolyOrder<=polyOrder_; totalPolyOrder++)
393 for (
int i=2; i<totalPolyOrder; i++)
395 const int edgeBasisOrdinal = edgeOrdinal*num1DEdgeFunctions + i-2 + numVertices;
396 const auto & grad_L_i_dx = output_(edgeBasisOrdinal,pointOrdinal,0);
397 const auto & grad_L_i_dy = output_(edgeBasisOrdinal,pointOrdinal,1);
398 const auto & grad_L_i_dz = output_(edgeBasisOrdinal,pointOrdinal,2);
400 const int alphaOrdinal = i-2;
402 const auto & s0_dx = lambda_dx[face_vertex_0[faceOrdinal]];
403 const auto & s0_dy = lambda_dy[face_vertex_0[faceOrdinal]];
404 const auto & s0_dz = lambda_dz[face_vertex_0[faceOrdinal]];
405 const auto & s1_dx = lambda_dx[face_vertex_1[faceOrdinal]];
406 const auto & s1_dy = lambda_dy[face_vertex_1[faceOrdinal]];
407 const auto & s1_dz = lambda_dz[face_vertex_1[faceOrdinal]];
408 const auto & s2_dx = lambda_dx[face_vertex_2[faceOrdinal]];
409 const auto & s2_dy = lambda_dy[face_vertex_2[faceOrdinal]];
410 const auto & s2_dz = lambda_dz[face_vertex_2[faceOrdinal]];
412 int j = totalPolyOrder - i;
415 auto & l_2i_j = L_2i_j(alphaOrdinal,j);
417 auto & l_2i_j_dt = L_2i_j_dt(alphaOrdinal,j);
418 auto & p_2i_j_minus_1 = P_2i_j_minus_1(alphaOrdinal,j-1);
420 const OutputScalar basisValue_dx = l_2i_j * grad_L_i_dx + l_i * (p_2i_j_minus_1 * s2_dx + l_2i_j_dt * (s0_dx + s1_dx + s2_dx));
421 const OutputScalar basisValue_dy = l_2i_j * grad_L_i_dy + l_i * (p_2i_j_minus_1 * s2_dy + l_2i_j_dt * (s0_dy + s1_dy + s2_dy));
422 const OutputScalar basisValue_dz = l_2i_j * grad_L_i_dz + l_i * (p_2i_j_minus_1 * s2_dz + l_2i_j_dt * (s0_dz + s1_dz + s2_dz));
424 const int fieldOrdinal = fieldOrdinalOffset + localFaceOrdinal;
426 output_(fieldOrdinal,pointOrdinal,0) = basisValue_dx;
427 output_(fieldOrdinal,pointOrdinal,1) = basisValue_dy;
428 output_(fieldOrdinal,pointOrdinal,2) = basisValue_dz;
433 fieldOrdinalOffset += numFaceBasisFunctionsPerFace;
452 auto & L_alpha = jacobi_values1_at_point;
453 auto & P_alpha = jacobi_values2_at_point;
457 const auto & s0 = lambda[0];
458 const auto & s1 = lambda[1];
459 const auto & s2 = lambda[2];
461 Polynomials::shiftedScaledIntegratedLegendreValues(legendre_values1_at_point, polyOrder_, PointScalar(s1), PointScalar(s0+s1));
464 const PointScalar jacobiScaling = s0 + s1 + s2;
465 for (
int n=2; n<=polyOrder_; n++)
467 const double alpha = n*2;
468 const int alphaOrdinal = n-2;
469 using Kokkos::subview;
471 auto jacobi_alpha = subview(jacobi_values3_at_point, alphaOrdinal, ALL);
472 Polynomials::integratedJacobiValues(jacobi_alpha, alpha, polyOrder_-2, s2, jacobiScaling);
477 for (
int n=3; n<=polyOrder_; n++)
479 const double alpha = n*2;
480 const double jacobiScaling = 1.0;
481 const int alphaOrdinal = n-3;
482 using Kokkos::subview;
486 auto L = subview(L_alpha, alphaOrdinal, ALL);
487 auto P = subview(P_alpha, alphaOrdinal, ALL);
488 Polynomials::integratedJacobiValues (L, alpha, polyOrder_-3, lambda[3], jacobiScaling);
489 Polynomials::shiftedScaledJacobiValues(P, alpha, polyOrder_-3, lambda[3], jacobiScaling);
495 const int min_ij = min_i + min_j;
496 const int min_ijk = min_ij + min_k;
497 int localInteriorBasisOrdinal = 0;
498 for (
int totalPolyOrder_ijk=min_ijk; totalPolyOrder_ijk <= polyOrder_; totalPolyOrder_ijk++)
500 int localFaceBasisOrdinal = 0;
501 for (
int totalPolyOrder_ij=min_ij; totalPolyOrder_ij <= totalPolyOrder_ijk-min_j; totalPolyOrder_ij++)
503 for (
int i=2; i <= totalPolyOrder_ij-min_j; i++)
505 const int j = totalPolyOrder_ij - i;
506 const int k = totalPolyOrder_ijk - totalPolyOrder_ij;
508 const int faceBasisOrdinal = numEdges*num1DEdgeFunctions + numVertices + localFaceBasisOrdinal;
510 const auto & faceValue_dx = output_(faceBasisOrdinal,pointOrdinal,0);
511 const auto & faceValue_dy = output_(faceBasisOrdinal,pointOrdinal,1);
512 const auto & faceValue_dz = output_(faceBasisOrdinal,pointOrdinal,2);
515 OutputScalar faceValue;
517 const auto & edgeValue = legendre_values1_at_point(i);
518 const int alphaOrdinal = i-2;
519 const auto & jacobiValue = jacobi_values3_at_point(alphaOrdinal,j);
520 faceValue = edgeValue * jacobiValue;
522 localFaceBasisOrdinal++;
524 const int alphaOrdinal = (i+j)-3;
526 const int fieldOrdinal = fieldOrdinalOffset + localInteriorBasisOrdinal;
527 const auto & integratedJacobiValue = L_alpha(alphaOrdinal,k);
528 const auto & jacobiValue = P_alpha(alphaOrdinal,k-1);
529 output_(fieldOrdinal,pointOrdinal,0) = integratedJacobiValue * faceValue_dx + faceValue * jacobiValue * lambda_dx[3];
530 output_(fieldOrdinal,pointOrdinal,1) = integratedJacobiValue * faceValue_dy + faceValue * jacobiValue * lambda_dy[3];
531 output_(fieldOrdinal,pointOrdinal,2) = integratedJacobiValue * faceValue_dz + faceValue * jacobiValue * lambda_dz[3];
533 localInteriorBasisOrdinal++;
537 fieldOrdinalOffset += numInteriorBasisFunctions;
549 INTREPID2_TEST_FOR_ABORT(
true,
550 ">>> ERROR: (Intrepid2::Basis_HGRAD_TET_Cn_FEM_ORTH::OrthPolynomialTri) Computing of second and higher-order derivatives is not currently supported");
553 device_assert(
false);
560 size_t team_shmem_size (
int team_size)
const
567 const int numAlphaValues = std::max(polyOrder_-1, 1);
568 size_t shmem_size = 0;
569 if (fad_size_output_ > 0)
572 shmem_size += 2 * OutputScratchView::shmem_size(polyOrder_ + 1, fad_size_output_);
574 shmem_size += 3 * OutputScratchView2D::shmem_size(numAlphaValues, polyOrder_ + 1, fad_size_output_);
579 shmem_size += 2 * OutputScratchView::shmem_size(polyOrder_ + 1);
581 shmem_size += 3 * OutputScratchView2D::shmem_size(numAlphaValues, polyOrder_ + 1);
605 template<
typename ExecutionSpace=Kokkos::DefaultExecutionSpace,
606 typename OutputScalar = double,
607 typename PointScalar = double,
608 bool defineVertexFunctions =
true>
610 :
public Basis<ExecutionSpace,OutputScalar,PointScalar>
621 bool defineVertexFunctions_;
635 polyOrder_(polyOrder)
639 this->
basisCellTopology_ = shards::CellTopology(shards::getCellTopologyData<shards::Tetrahedron<> >() );
644 const int degreeLength = 1;
647 int fieldOrdinalOffset = 0;
650 const int numFunctionsPerVertex = 1;
651 const int numVertexFunctions = numVertices * numFunctionsPerVertex;
652 for (
int i=0; i<numVertexFunctions; i++)
658 if (!defineVertexFunctions)
662 fieldOrdinalOffset += numVertexFunctions;
665 const int numFunctionsPerEdge = polyOrder - 1;
667 for (
int edgeOrdinal=0; edgeOrdinal<numEdges; edgeOrdinal++)
669 for (
int i=0; i<numFunctionsPerEdge; i++)
673 fieldOrdinalOffset += numFunctionsPerEdge;
677 const int numFunctionsPerFace = ((polyOrder-1)*(polyOrder-2))/2;
678 const int numFaces = 4;
679 for (
int faceOrdinal=0; faceOrdinal<numFaces; faceOrdinal++)
681 for (
int totalPolyOrder=3; totalPolyOrder<=polyOrder_; totalPolyOrder++)
683 const int totalFaceDofs = (totalPolyOrder-2)*(totalPolyOrder-1)/2;
684 const int totalFaceDofsPrevious = (totalPolyOrder-3)*(totalPolyOrder-2)/2;
685 const int faceDofsForPolyOrder = totalFaceDofs - totalFaceDofsPrevious;
686 for (
int i=0; i<faceDofsForPolyOrder; i++)
689 fieldOrdinalOffset++;
695 const int numFunctionsPerVolume = ((polyOrder-1)*(polyOrder-2)*(polyOrder-3))/6;
696 const int numVolumes = 1;
697 for (
int volumeOrdinal=0; volumeOrdinal<numVolumes; volumeOrdinal++)
699 for (
int totalPolyOrder=4; totalPolyOrder<=polyOrder_; totalPolyOrder++)
701 const int totalInteriorDofs = (totalPolyOrder-3)*(totalPolyOrder-2)*(totalPolyOrder-1)/6;
702 const int totalInteriorDofsPrevious = (totalPolyOrder-4)*(totalPolyOrder-3)*(totalPolyOrder-2)/6;
703 const int interiorDofsForPolyOrder = totalInteriorDofs - totalInteriorDofsPrevious;
705 for (
int i=0; i<interiorDofsForPolyOrder; i++)
708 fieldOrdinalOffset++;
713 INTREPID2_TEST_FOR_EXCEPTION(fieldOrdinalOffset != this->
basisCardinality_, std::invalid_argument,
"Internal error: basis enumeration is incorrect");
720 const int intrepid2FaceOrdinals[4] {3,0,1,2};
725 const ordinal_type tagSize = 4;
726 const ordinal_type posScDim = 0;
727 const ordinal_type posScOrd = 1;
728 const ordinal_type posDfOrd = 2;
730 OrdinalTypeArray1DHost tagView(
"tag view", cardinality*tagSize);
731 const int vertexDim = 0, edgeDim = 1, faceDim = 2, volumeDim = 3;
733 if (defineVertexFunctions) {
736 for (
int vertexOrdinal=0; vertexOrdinal<numVertices; vertexOrdinal++)
738 for (
int functionOrdinal=0; functionOrdinal<numFunctionsPerVertex; functionOrdinal++)
740 tagView(tagNumber*tagSize+0) = vertexDim;
741 tagView(tagNumber*tagSize+1) = vertexOrdinal;
742 tagView(tagNumber*tagSize+2) = functionOrdinal;
743 tagView(tagNumber*tagSize+3) = numFunctionsPerVertex;
747 for (
int edgeOrdinal=0; edgeOrdinal<numEdges; edgeOrdinal++)
749 for (
int functionOrdinal=0; functionOrdinal<numFunctionsPerEdge; functionOrdinal++)
751 tagView(tagNumber*tagSize+0) = edgeDim;
752 tagView(tagNumber*tagSize+1) = edgeOrdinal;
753 tagView(tagNumber*tagSize+2) = functionOrdinal;
754 tagView(tagNumber*tagSize+3) = numFunctionsPerEdge;
758 for (
int faceOrdinalESEAS=0; faceOrdinalESEAS<numFaces; faceOrdinalESEAS++)
760 int faceOrdinalIntrepid2 = intrepid2FaceOrdinals[faceOrdinalESEAS];
761 for (
int functionOrdinal=0; functionOrdinal<numFunctionsPerFace; functionOrdinal++)
763 tagView(tagNumber*tagSize+0) = faceDim;
764 tagView(tagNumber*tagSize+1) = faceOrdinalIntrepid2;
765 tagView(tagNumber*tagSize+2) = functionOrdinal;
766 tagView(tagNumber*tagSize+3) = numFunctionsPerFace;
770 for (
int volumeOrdinal=0; volumeOrdinal<numVolumes; volumeOrdinal++)
772 for (
int functionOrdinal=0; functionOrdinal<numFunctionsPerVolume; functionOrdinal++)
774 tagView(tagNumber*tagSize+0) = volumeDim;
775 tagView(tagNumber*tagSize+1) = volumeOrdinal;
776 tagView(tagNumber*tagSize+2) = functionOrdinal;
777 tagView(tagNumber*tagSize+3) = numFunctionsPerVolume;
781 INTREPID2_TEST_FOR_EXCEPTION(tagNumber != this->
basisCardinality_, std::invalid_argument,
"Internal error: basis tag enumeration is incorrect");
784 for (ordinal_type i=0;i<cardinality;++i) {
785 tagView(i*tagSize+0) = volumeDim;
786 tagView(i*tagSize+1) = 0;
787 tagView(i*tagSize+2) = i;
788 tagView(i*tagSize+3) = cardinality;
810 return "Intrepid2_IntegratedLegendreBasis_HGRAD_TET";
842 virtual void getValues( OutputViewType outputValues,
const PointViewType inputPoints,
843 const EOperator operatorType = OPERATOR_VALUE )
const override
845 auto numPoints = inputPoints.extent_int(0);
849 FunctorType functor(operatorType, outputValues, inputPoints, polyOrder_, defineVertexFunctions);
851 const int outputVectorSize = getVectorSizeForHierarchicalParallelism<OutputScalar>();
852 const int pointVectorSize = getVectorSizeForHierarchicalParallelism<PointScalar>();
853 const int vectorSize = std::max(outputVectorSize,pointVectorSize);
854 const int teamSize = 1;
856 auto policy = Kokkos::TeamPolicy<ExecutionSpace>(numPoints,teamSize,vectorSize);
857 Kokkos::parallel_for( policy , functor,
"Hierarchical_HGRAD_TET_Functor");
Free functions, callable from device code, that implement various polynomials useful in basis definit...
Header function for Intrepid2::Util class and other utility functions.
constexpr KOKKOS_INLINE_FUNCTION unsigned getScalarDimensionForView(const ViewType &view)
Returns the size of the Scalar dimension for the View. This is 0 for non-AD types....
An abstract base class that defines interface for concrete basis implementations for Finite Element (...
Kokkos::DynRankView< PointValueType, Kokkos::LayoutStride, ExecSpaceType > PointViewType
View type for input points.
EBasis basisType_
Type of the basis.
ECoordinates basisCoordinates_
The coordinate system for which the basis is defined.
shards::CellTopology basisCellTopology_
Base topology of the cells for which the basis is defined. See the Shards package for definition of b...
EFunctionSpace functionSpace_
The function space in which the basis is defined.
Kokkos::View< ordinal_type *, typename ExecSpaceType::array_layout, Kokkos::HostSpace > OrdinalTypeArray1DHost
View type for 1d host array.
OrdinalTypeArray3DHost tagToOrdinal_
DoF tag to ordinal lookup table.
ordinal_type getDegree() const
Returns the degree of the basis.
ordinal_type basisCardinality_
Cardinality of the basis, i.e., the number of basis functions/degrees-of-freedom.
Kokkos::DynRankView< scalarType, Kokkos::LayoutStride, ExecSpaceType > ScalarViewType
View type for scalars.
ordinal_type basisDegree_
Degree of the largest complete polynomial space that can be represented by the basis.
Kokkos::View< ordinal_type **, typename ExecSpaceType::array_layout, Kokkos::HostSpace > OrdinalTypeArray2DHost
View type for 2d host array.
OrdinalTypeArray2DHost ordinalToTag_
"true" if tagToOrdinal_ and ordinalToTag_ have been initialized
Kokkos::DynRankView< OutputValueType, Kokkos::LayoutStride, ExecSpaceType > OutputViewType
View type for basis value output.
OrdinalTypeArray2DHost fieldOrdinalPolynomialDegree_
Polynomial degree for each degree of freedom. Only defined for hierarchical bases right now....
void setOrdinalTagData(OrdinalTypeView3D &tagToOrdinal, OrdinalTypeView2D &ordinalToTag, const OrdinalTypeView1D tags, const ordinal_type basisCard, const ordinal_type tagSize, const ordinal_type posScDim, const ordinal_type posScOrd, const ordinal_type posDfOrd)
Fills ordinalToTag_ and tagToOrdinal_ by basis-specific tag data.
Basis defining integrated Legendre basis on the line, a polynomial subspace of H(grad) on the line.
const char * getName() const override
Returns basis name.
IntegratedLegendreBasis_HGRAD_TET(int polyOrder)
Constructor.
virtual void getValues(OutputViewType outputValues, const PointViewType inputPoints, const EOperator operatorType=OPERATOR_VALUE) const override
Evaluation of a FEM basis on a reference cell.
virtual bool requireOrientation() const override
True if orientation is required.
Functor for computing values for the IntegratedLegendreBasis_HGRAD_TET class.