15 #ifndef Intrepid2_LegendreBasis_HVOL_TET_h
16 #define Intrepid2_LegendreBasis_HVOL_TET_h
18 #include <Kokkos_DynRankView.hpp>
20 #include <Intrepid2_config.h>
35 template<
class DeviceType,
class OutputScalar,
class PointScalar,
36 class OutputFieldType,
class InputPointsType>
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_;
53 int numFields_, numPoints_;
55 size_t fad_size_output_;
58 : opType_(opType), output_(output), inputPoints_(inputPoints),
59 polyOrder_(polyOrder),
60 fad_size_output_(getScalarDimensionForView(output))
62 numFields_ = output.extent_int(0);
63 numPoints_ = output.extent_int(1);
64 INTREPID2_TEST_FOR_EXCEPTION(numPoints_ != inputPoints.extent_int(0), std::invalid_argument,
"point counts need to match!");
65 INTREPID2_TEST_FOR_EXCEPTION(numFields_ != (polyOrder_+1)*(polyOrder_+2)*(polyOrder_+3)/6, std::invalid_argument,
"output field size does not match basis cardinality");
68 KOKKOS_INLINE_FUNCTION
69 void operator()(
const TeamMember & teamMember )
const
81 auto pointOrdinal = teamMember.league_rank();
82 OutputScratchView P, P_2p1, P_2ipjp1;
83 if (fad_size_output_ > 0) {
84 P = OutputScratchView(teamMember.team_shmem(), polyOrder_ + 1, fad_size_output_);
85 P_2p1 = OutputScratchView(teamMember.team_shmem(), polyOrder_ + 1, fad_size_output_);
86 P_2ipjp1 = OutputScratchView(teamMember.team_shmem(), polyOrder_ + 1, fad_size_output_);
89 P = OutputScratchView(teamMember.team_shmem(), polyOrder_ + 1);
90 P_2p1 = OutputScratchView(teamMember.team_shmem(), polyOrder_ + 1);
91 P_2ipjp1 = OutputScratchView(teamMember.team_shmem(), polyOrder_ + 1);
94 const auto & x = inputPoints_(pointOrdinal,0);
95 const auto & y = inputPoints_(pointOrdinal,1);
96 const auto & z = inputPoints_(pointOrdinal,2);
99 const PointScalar lambda[4] = {1. - x - y - z, x, y, z};
107 const PointScalar tLegendre = lambda[0] + lambda[1];
108 Polynomials::shiftedScaledLegendreValues(P, polyOrder_, lambda[1], tLegendre);
110 int fieldOrdinalOffset = 0;
115 const int min_ij = min_i + min_j;
116 const int min_ijk = min_ij + min_k;
117 for (
int totalPolyOrder_ijk=min_ijk; totalPolyOrder_ijk <= polyOrder_; totalPolyOrder_ijk++)
119 for (
int totalPolyOrder_ij=min_ij; totalPolyOrder_ij <= totalPolyOrder_ijk-min_j; totalPolyOrder_ij++)
121 for (
int i=min_i; i <= totalPolyOrder_ij-min_j; i++)
123 const int j = totalPolyOrder_ij - i;
124 const int k = totalPolyOrder_ijk - totalPolyOrder_ij;
126 const double alpha1 = i * 2.0 + 1.;
127 const PointScalar tJacobi1 = lambda[0] + lambda[1] + lambda[2];
128 const PointScalar & xJacobi1 = lambda[2];
129 Polynomials::shiftedScaledJacobiValues(P_2p1, alpha1, polyOrder_, xJacobi1, tJacobi1);
131 const double alpha2 = 2. * (i + j + 1.);
132 const PointScalar tJacobi2 = 1.0;
133 const PointScalar & xJacobi2 = lambda[3];
134 Polynomials::shiftedScaledJacobiValues(P_2ipjp1, alpha2, polyOrder_, xJacobi2, tJacobi2);
136 const auto & P_i = P(i);
137 const auto & P_2p1_j = P_2p1(j);
138 const auto & P_2ipjp1_k = P_2ipjp1(k);
140 output_(fieldOrdinalOffset,pointOrdinal) = P_i * P_2p1_j * P_2ipjp1_k;
141 fieldOrdinalOffset++;
150 device_assert(
false);
157 size_t team_shmem_size (
int team_size)
const
160 size_t shmem_size = 0;
161 if (fad_size_output_ > 0)
162 shmem_size += 3 * OutputScratchView::shmem_size(polyOrder_ + 1, fad_size_output_);
164 shmem_size += 3 * OutputScratchView::shmem_size(polyOrder_ + 1);
180 template<
typename DeviceType,
181 typename OutputScalar = double,
182 typename PointScalar =
double>
184 :
public Basis<DeviceType,OutputScalar,PointScalar>
200 EPointType pointType_;
210 polyOrder_(polyOrder),
211 pointType_(pointType)
213 INTREPID2_TEST_FOR_EXCEPTION(pointType!=POINTTYPE_DEFAULT,std::invalid_argument,
"PointType not supported");
222 const int degreeLength = 1;
225 int fieldOrdinalOffset = 0;
230 const int min_ij = min_i + min_j;
231 const int min_ijk = min_ij + min_k;
232 for (
int totalPolyOrder_ijk=min_ijk; totalPolyOrder_ijk <= polyOrder_; totalPolyOrder_ijk++)
234 for (
int totalPolyOrder_ij=min_ij; totalPolyOrder_ij <= totalPolyOrder_ijk-min_j; totalPolyOrder_ij++)
236 for (
int i=min_i; i <= totalPolyOrder_ij-min_j; i++)
238 const int j = totalPolyOrder_ij - i;
239 const int k = totalPolyOrder_ijk - totalPolyOrder_ij;
242 fieldOrdinalOffset++;
246 INTREPID2_TEST_FOR_EXCEPTION(fieldOrdinalOffset != this->
basisCardinality_, std::invalid_argument,
"Internal error: basis enumeration is incorrect");
253 const ordinal_type tagSize = 4;
254 const ordinal_type posScDim = 0;
255 const ordinal_type posScOrd = 1;
256 const ordinal_type posDfOrd = 2;
259 const int volumeDim = 3;
261 for (ordinal_type i=0;i<cardinality;++i) {
262 tagView(i*tagSize+0) = volumeDim;
263 tagView(i*tagSize+1) = 0;
264 tagView(i*tagSize+2) = i;
265 tagView(i*tagSize+3) = cardinality;
286 return "Intrepid2_LegendreBasis_HVOL_TET";
319 const EOperator operatorType = OPERATOR_VALUE )
const override
321 auto numPoints = inputPoints.extent_int(0);
325 FunctorType functor(operatorType, outputValues, inputPoints, polyOrder_);
327 const int outputVectorSize = getVectorSizeForHierarchicalParallelism<OutputScalar>();
328 const int pointVectorSize = getVectorSizeForHierarchicalParallelism<PointScalar>();
329 const int vectorSize = std::max(outputVectorSize,pointVectorSize);
330 const int teamSize = 1;
332 auto policy = Kokkos::TeamPolicy<ExecutionSpace>(numPoints,teamSize,vectorSize);
333 Kokkos::parallel_for(
"Hierarchical_HVOL_TET_Functor", policy , functor);
340 virtual BasisPtr<typename Kokkos::HostSpace::device_type, OutputScalar, PointScalar>
342 using HostDeviceType =
typename Kokkos::HostSpace::device_type;
344 return Teuchos::rcp(
new HostBasisType(polyOrder_, pointType_) );
Kokkos::View< ordinal_type *, typename ExecutionSpace::array_layout, Kokkos::HostSpace > OrdinalTypeArray1DHost
View type for 1d host array.
const char * getName() const override
Returns basis name.
LegendreBasis_HVOL_TET(int polyOrder, const EPointType pointType=POINTTYPE_DEFAULT)
Constructor.
unsigned basisCellTopologyKey_
Identifier of the base topology of the cells for which the basis is defined. See the Shards package f...
EBasis basisType_
Type of the basis.
virtual BasisPtr< typename Kokkos::HostSpace::device_type, OutputScalar, PointScalar > getHostBasis() const override
Creates and returns a Basis object whose DeviceType template argument is Kokkos::HostSpace::device_ty...
An abstract base class that defines interface for concrete basis implementations for Finite Element (...
Kokkos::View< ordinal_type *, typename ExecutionSpace::array_layout, Kokkos::HostSpace > OrdinalTypeArray1DHost
View type for 1d host array.
Kokkos::DynRankView< scalarType, Kokkos::LayoutStride, DeviceType > ScalarViewType
View type for scalars.
virtual bool requireOrientation() const override
True if orientation is required.
Functor for computing values for the LegendreBasis_HVOL_TET class.
Free functions, callable from device code, that implement various polynomials useful in basis definit...
EFunctionSpace functionSpace_
The function space in which the basis is defined.
ordinal_type basisDegree_
Degree of the largest complete polynomial space that can be represented by the basis.
virtual KOKKOS_INLINE_FUNCTION void getValues(OutputViewType, const PointViewType, const EOperator, const typename Kokkos::TeamPolicy< ExecutionSpace >::member_type &teamMember, const typename ExecutionSpace::scratch_memory_space &scratchStorage, const ordinal_type subcellDim=-1, const ordinal_type subcellOrdinal=-1) const
Team-level evaluation of basis functions on a reference cell.
Header function for Intrepid2::Util class and other utility functions.
Kokkos::DynRankView< PointValueType, Kokkos::LayoutStride, DeviceType > PointViewType
View type for input points.
Kokkos::View< ordinal_type **, typename ExecutionSpace::array_layout, Kokkos::HostSpace > OrdinalTypeArray2DHost
View type for 2d host array.
Kokkos::DynRankView< OutputValueType, Kokkos::LayoutStride, DeviceType > OutputViewType
View type for basis value output.
H(vol) basis on the line based on Legendre polynomials.
ordinal_type basisCardinality_
Cardinality of the basis, i.e., the number of basis functions/degrees-of-freedom. ...
OrdinalTypeArray3DHost tagToOrdinal_
DoF tag to ordinal lookup table.
Basis defining Legendre basis on the line, a polynomial subspace of H(vol) on the line: extension to ...
virtual void getValues(OutputViewType outputValues, const PointViewType inputPoints, const EOperator operatorType=OPERATOR_VALUE) const override
Evaluation of a FEM basis on a reference cell.
OrdinalTypeArray2DHost ordinalToTag_
"true" if tagToOrdinal_ and ordinalToTag_ have been initialized
ordinal_type getDegree() const
Returns the degree of the basis.
ECoordinates basisCoordinates_
The coordinate system for which the basis is defined.
OrdinalTypeArray2DHost fieldOrdinalPolynomialDegree_
Polynomial degree for each degree of freedom. Only defined for hierarchical bases right now...
Kokkos::DynRankView< OutputValueType, Kokkos::LayoutStride, DeviceType > OutputViewType
View type for basis value output.
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.
H(vol) basis on the triangle based on integrated Legendre polynomials.
Kokkos::DynRankView< PointValueType, Kokkos::LayoutStride, DeviceType > PointViewType
View type for input points.
Header file for the abstract base class Intrepid2::Basis.
typename DeviceType::execution_space ExecutionSpace
(Kokkos) Execution space for basis.