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),
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++;
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);
342 using HostDeviceType =
typename Kokkos::HostSpace::device_type;
344 return Teuchos::rcp(
new HostBasisType(polyOrder_, pointType_) );
Header file for the abstract base class Intrepid2::Basis.
Teuchos::RCP< Basis< DeviceType, OutputType, PointType > > BasisPtr
Basis Pointer.
KOKKOS_INLINE_FUNCTION void device_assert(bool val)
H(vol) basis on the line based on Legendre polynomials.
H(vol) basis on the triangle based on integrated Legendre polynomials.
Free functions, callable from device code, that implement various polynomials useful in basis definit...
Header function for Intrepid2::Util class and other utility functions.
KOKKOS_INLINE_FUNCTION constexpr 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 (...
ECoordinates basisCoordinates_
The coordinate system for which the basis is defined.
Kokkos::DynRankView< PointValueType, Kokkos::LayoutStride, DeviceType > PointViewType
View type for input points.
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.
Kokkos::DynRankView< OutputValueType, Kokkos::LayoutStride, DeviceType > OutputViewType
View type for basis value output.
EBasis basisType_
Type of the basis.
ordinal_type basisDegree_
Degree of the largest complete polynomial space that can be represented by the basis.
ordinal_type getDegree() const
Returns the degree of the basis.
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.
Kokkos::DynRankView< scalarType, Kokkos::LayoutStride, DeviceType > ScalarViewType
View type for scalars.
OrdinalTypeArray2DHost ordinalToTag_
"true" if tagToOrdinal_ and ordinalToTag_ have been initialized
Kokkos::View< ordinal_type **, typename ExecutionSpace::array_layout, Kokkos::HostSpace > OrdinalTypeArray2DHost
View type for 2d host array.
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.
Kokkos::View< ordinal_type *, typename ExecutionSpace::array_layout, Kokkos::HostSpace > OrdinalTypeArray1DHost
View type for 1d host array.
unsigned basisCellTopologyKey_
Identifier of the base topology of the cells for which the basis is defined. See the Shards package f...
typename DeviceType::execution_space ExecutionSpace
(Kokkos) Execution space for basis.
OrdinalTypeArray2DHost fieldOrdinalPolynomialDegree_
Polynomial degree for each degree of freedom. Only defined for hierarchical bases right now....
EFunctionSpace functionSpace_
The function space in which the basis is defined.
Basis defining Legendre basis on the line, a polynomial subspace of H(vol) on the line: extension to ...
Kokkos::DynRankView< PointValueType, Kokkos::LayoutStride, DeviceType > PointViewType
View type for input points.
Kokkos::DynRankView< OutputValueType, Kokkos::LayoutStride, DeviceType > OutputViewType
View type for basis value output.
virtual void getValues(OutputViewType outputValues, const PointViewType inputPoints, const EOperator operatorType=OPERATOR_VALUE) const override
Evaluation of a FEM basis on a reference cell.
const char * getName() const override
Returns basis name.
LegendreBasis_HVOL_TET(int polyOrder, const EPointType pointType=POINTTYPE_DEFAULT)
Constructor.
Kokkos::View< ordinal_type **, typename ExecutionSpace::array_layout, Kokkos::HostSpace > OrdinalTypeArray2DHost
View type for 2d host array.
virtual bool requireOrientation() const override
True if orientation is required.
Kokkos::View< ordinal_type *, typename ExecutionSpace::array_layout, Kokkos::HostSpace > OrdinalTypeArray1DHost
View type for 1d host array.
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...
Functor for computing values for the LegendreBasis_HVOL_TET class.