16 #ifndef Intrepid2_TensorPoints_h
17 #define Intrepid2_TensorPoints_h
19 #include <Kokkos_Core.hpp>
25 template<
class Po
intScalar,
typename DeviceType>
28 using value_type = PointScalar;
31 ordinal_type numTensorComponents_;
32 ordinal_type totalPointCount_;
33 ordinal_type totalDimension_;
34 Kokkos::View<ordinal_type*, DeviceType> dimToComponent_;
35 Kokkos::View<ordinal_type*, DeviceType> dimToComponentDim_;
36 Kokkos::Array<ordinal_type, Parameters::MaxTensorComponents> pointModulus_;
37 Kokkos::Array<ordinal_type, Parameters::MaxTensorComponents> pointDivisor_;
40 using reference_type =
typename ScalarView<PointScalar,DeviceType>::reference_type;
42 void TEST_VALID_POINT_COMPONENTS()
44 #ifdef HAVE_INTREPID2_DEBUG
47 for (ordinal_type r=0; r<numTensorComponents_; r++)
49 const auto & pointComponent = pointTensorComponents_[r];
50 INTREPID2_TEST_FOR_EXCEPTION(2 != pointComponent.rank(), std::invalid_argument,
"Each component must have shape (P,D)");
51 INTREPID2_TEST_FOR_EXCEPTION(pointComponent.extent_int(0) <= 0, std::invalid_argument,
"Each component must have at least one point");
62 TEST_VALID_POINT_COMPONENTS();
66 for (ordinal_type r=0; r<numTensorComponents_; r++)
68 totalPointCount_ *= pointTensorComponents_[r].extent_int(0);
69 totalDimension_ += pointTensorComponents_[r].extent_int(1);
71 ordinal_type pointDivisor = 1;
72 for (ordinal_type r=0; r<numTensorComponents_; r++)
74 pointModulus_[r] = pointTensorComponents_[r].extent_int(0);
75 pointDivisor_[r] = pointDivisor;
76 pointDivisor *= pointTensorComponents_[r].extent_int(0);
78 dimToComponent_ = Kokkos::View<ordinal_type*, DeviceType>(
"dimToComponent_",totalDimension_);
79 dimToComponentDim_ = Kokkos::View<ordinal_type*, DeviceType>(
"dimToComponentDim_",totalDimension_);
81 ordinal_type dimsSoFar = 0;
83 auto dimToComponentHost = Kokkos::create_mirror_view(dimToComponent_);
84 auto dimToComponentDimHost = Kokkos::create_mirror_view(dimToComponentDim_);
85 for (ordinal_type r=0; r<numTensorComponents_; r++)
87 const int componentDim = pointTensorComponents_[r].extent_int(1);
88 for (
int i=0; i<componentDim; i++)
90 dimToComponentHost[d] = r;
91 dimToComponentDimHost[d] = d - dimsSoFar;
94 dimsSoFar += componentDim;
96 Kokkos::deep_copy(dimToComponent_,dimToComponentHost);
97 Kokkos::deep_copy(dimToComponentDim_,dimToComponentDimHost);
106 template<
size_t numTensorComponents>
114 pointTensorComponents_[r] = pointTensorComponents[r];
129 numTensorComponents_(whichDims.size()),
133 for (
const auto & componentOrdinal : whichDims)
135 pointTensorComponents_[r++] = otherPointsContainer.
getTensorComponent(componentOrdinal);
147 TensorPoints(std::vector< ScalarView<PointScalar,DeviceType>> pointTensorComponents)
149 numTensorComponents_(pointTensorComponents.size()),
152 for (ordinal_type r=0; r<numTensorComponents_; r++)
154 pointTensorComponents_[r] = pointTensorComponents[r];
168 numTensorComponents_(1),
171 pointTensorComponents_[0] = points;
180 template<
class OtherPo
intsContainer>
183 const int numPoints = fromPoints.extent_int(0);
184 const int numDims = fromPoints.extent_int(1);
185 using ExecutionSpace =
typename DeviceType::execution_space;
186 auto policy = Kokkos::MDRangePolicy<ExecutionSpace,Kokkos::Rank<2>>({0,0},{numPoints,numDims});
187 Kokkos::parallel_for(
"copy points", policy,
188 KOKKOS_LAMBDA (
const int &i0,
const int &i1) {
189 toPoints(i0,i1) = fromPoints(i0,i1);
194 template<typename OtherDeviceType, class = typename std::enable_if< std::is_same<typename DeviceType::memory_space, typename OtherDeviceType::memory_space>::value>::type,
195 class = typename std::enable_if<!std::is_same<DeviceType,OtherDeviceType>::value>::type>
196 TensorPoints(const TensorPoints<PointScalar,OtherDeviceType> &tensorPoints)
198 numTensorComponents_(tensorPoints.numTensorComponents()),
199 isValid_(tensorPoints.isValid())
203 for (ordinal_type r=0; r<numTensorComponents_; r++)
212 template<typename OtherDeviceType, class = typename std::enable_if<!std::is_same<typename DeviceType::memory_space, typename OtherDeviceType::memory_space>::value>::type>
216 isValid_(tensorPoints.
isValid())
220 for (ordinal_type r=0; r<numTensorComponents_; r++)
222 ScalarView<PointScalar,OtherDeviceType> otherPointComponent = tensorPoints.
getTensorComponent(r);
223 const int numPoints = otherPointComponent.extent_int(0);
224 const int numDims = otherPointComponent.extent_int(1);
225 pointTensorComponents_[r] = ScalarView<PointScalar,DeviceType>(
"Intrepid2 point component", numPoints, numDims);
227 using MemorySpace =
typename DeviceType::memory_space;
228 auto pointComponentMirror = Kokkos::create_mirror_view_and_copy(MemorySpace(), otherPointComponent);
247 return pointTensorComponents_[tensorComponentOrdinal].extent_int(0);
258 template <
typename iType0,
typename iType1>
259 KOKKOS_INLINE_FUNCTION
typename std::enable_if<
260 (std::is_integral<iType0>::value && std::is_integral<iType1>::value),
261 reference_type>::type
262 operator()(
const iType0& tensorPointIndex,
const iType1& dim)
const {
263 const ordinal_type component = dimToComponent_[dim];
264 const ordinal_type d = dimToComponentDim_[dim];
265 const ordinal_type componentPointOrdinal = (tensorPointIndex / pointDivisor_[component]) % pointModulus_[component];
266 return pointTensorComponents_[component](componentPointOrdinal,d);
277 template <
typename iType0,
typename iType1,
size_t numTensorComponents>
278 KOKKOS_INLINE_FUNCTION
typename std::enable_if<
279 (std::is_integral<iType0>::value && std::is_integral<iType1>::value),
280 reference_type>::type
281 operator()(
const Kokkos::Array<iType0,numTensorComponents>& pointOrdinalComponents,
const iType1& dim)
const {
282 const ordinal_type component = dimToComponent_[dim];
283 const ordinal_type d = dimToComponentDim_[dim];
284 const ordinal_type componentPointOrdinal = pointOrdinalComponents[component];
285 return pointTensorComponents_[component](componentPointOrdinal,d);
293 template <
typename iType>
294 KOKKOS_INLINE_FUNCTION
295 typename std::enable_if<std::is_integral<iType>::value,
int>::type
297 if (r == static_cast<iType>(0))
299 return totalPointCount_;
301 else if (r == static_cast<iType>(1))
303 return totalDimension_;
316 template <
typename iType>
317 KOKKOS_INLINE_FUNCTION constexpr
318 typename std::enable_if<std::is_integral<iType>::value,
size_t>::type
321 return (r == static_cast<iType>(0)) ? totalPointCount_
323 (r ==
static_cast<iType
>(1)) ? totalDimension_ : 1;
331 ScalarView<PointScalar,DeviceType> expandedRawPoints(
"expanded raw points from TensorPoints", numPoints, spaceDim);
333 using ExecutionSpace =
typename DeviceType::execution_space;
334 Kokkos::parallel_for(
335 Kokkos::MDRangePolicy<ExecutionSpace,Kokkos::Rank<2>>({0,0},{numPoints,spaceDim}),
336 KOKKOS_LAMBDA (
const int &pointOrdinal,
const int &d) {
337 expandedRawPoints(pointOrdinal,d) = tensorPoints(pointOrdinal,d);
339 return expandedRawPoints;
347 KOKKOS_INLINE_FUNCTION
350 return pointTensorComponents_[r];
354 KOKKOS_INLINE_FUNCTION
361 KOKKOS_INLINE_FUNCTION
364 return numTensorComponents_;
368 KOKKOS_INLINE_FUNCTION
369 constexpr ordinal_type
rank()
const
TensorPoints(ScalarView< PointScalar, DeviceType > points)
Constructor for point set with trivial tensor structure.
KOKKOS_INLINE_FUNCTION bool isValid() const
Returns true for containers that have data; false for those that don't (e.g., those that have been co...
View-like interface to tensor points; point components are stored separately; the appropriate coordin...
void initialize()
Initialize members based on constructor parameters.
TensorPoints(const TensorPoints< PointScalar, OtherDeviceType > &tensorPoints)
copy-like constructor for differing memory spaces. This does a deep_copy of the underlying view...
void copyPointsContainer(ScalarView< PointScalar, DeviceType > toPoints, OtherPointsContainer fromPoints)
Copy from one points container, which may be an arbitrary functor, to a DynRankView.
ScalarView< PointScalar, DeviceType > allocateAndFillExpandedRawPointView() const
This method is for compatibility with existing methods that take raw point views. Note that in genera...
KOKKOS_INLINE_FUNCTION constexpr ordinal_type rank() const
Return the rank of the container, which is 2.
KOKKOS_INLINE_FUNCTION constexpr std::enable_if< std::is_integral< iType >::value, size_t >::type extent(const iType &r) const
Returns the logical extent in the requested dimension.
TensorPoints(TensorPoints otherPointsContainer, std::vector< int > whichDims)
Constructor that takes a subset of the tensorial components of another points container.
TensorPoints(Kokkos::Array< ScalarView< PointScalar, DeviceType >, numTensorComponents > pointTensorComponents)
Constructor with fixed-length Kokkos::Array argument.
KOKKOS_INLINE_FUNCTION ordinal_type numTensorComponents() const
Returns the number of tensorial components.
TensorPoints()
Default constructor. TensorPoints::isValid() will return false.
ordinal_type componentPointCount(const ordinal_type &tensorComponentOrdinal) const
Returns the number of points in the indicated component.
KOKKOS_INLINE_FUNCTION ScalarView< PointScalar, DeviceType > getTensorComponent(const ordinal_type &r) const
Returns the requested tensor component.
KOKKOS_INLINE_FUNCTION std::enable_if< std::is_integral< iType >::value, int >::type extent_int(const iType &r) const
Returns the logical extent in the requested dimension.
TensorPoints(std::vector< ScalarView< PointScalar, DeviceType >> pointTensorComponents)
Constructor with variable-length std::vector argument.
static constexpr ordinal_type MaxTensorComponents
Maximum number of tensor/Cartesian products that can be taken: this allows hypercube basis in 7D to b...