18#ifndef Intrepid2_BasisValues_h
19#define Intrepid2_BasisValues_h
34 template<
class Scalar,
typename DeviceType>
38 using value_type = Scalar;
43 Kokkos::Array<TensorDataType,Parameters::MaxTensorComponents> tensorDataFamilies_;
46 int numTensorDataFamilies_ = -1;
48 Kokkos::View<ordinal_type*,DeviceType> ordinalFilter_;
54 numTensorDataFamilies_(1)
62 for (
int family=0; family<numTensorDataFamilies_; family++)
77 numTensorDataFamilies_(0)
82 template<typename OtherDeviceType, class = typename std::enable_if<!std::is_same<DeviceType, OtherDeviceType>::value>::type>
86 numTensorDataFamilies_(basisValues.numTensorDataFamilies())
89 for (
int family=0; family<numTensorDataFamilies_; family++)
93 auto otherOrdinalFilter = basisValues.ordinalFilter();
94 ordinalFilter_ = Kokkos::View<ordinal_type*,DeviceType>(
"BasisValues::ordinalFilter_",otherOrdinalFilter.extent(0));
96 Kokkos::deep_copy(ordinalFilter_, otherOrdinalFilter);
102 int familyStartOrdinal = -1, familyEndOrdinal = -1;
105 for (
int i=0; i<familyCount; i++)
107 const bool startMatches = (fieldsSoFar == fieldStartOrdinal);
108 familyStartOrdinal = startMatches ? i : familyStartOrdinal;
109 fieldsSoFar += numFieldsInFamily(i);
110 const bool endMatches = (fieldsSoFar - fieldStartOrdinal == numFields);
111 familyEndOrdinal = endMatches ? i : familyEndOrdinal;
113 INTREPID2_TEST_FOR_EXCEPTION(familyStartOrdinal == -1, std::invalid_argument,
"fieldStartOrdinal does not align with the start of a family.");
114 INTREPID2_TEST_FOR_EXCEPTION(familyEndOrdinal == -1, std::invalid_argument,
"fieldStartOrdinal + numFields does not align with the end of a family.");
116 const int numFamiliesInFieldSpan = familyEndOrdinal - familyStartOrdinal + 1;
117 if (numTensorDataFamilies_ > 0)
120 for (
int i=familyStartOrdinal; i<=familyEndOrdinal; i++)
129 std::vector< std::vector<TensorData<Scalar,DeviceType> > > vectorComponents(numFamiliesInFieldSpan, std::vector<
TensorData<Scalar,DeviceType> >(componentCount));
130 for (
int i=familyStartOrdinal; i<=familyEndOrdinal; i++)
132 for (
int j=0; j<componentCount; j++)
134 vectorComponents[i-familyStartOrdinal][j] = vectorData_.
getComponent(i,j);
142 KOKKOS_INLINE_FUNCTION
152 for (
int i=0; i<familyOrdinal; i++)
154 offset += tensorDataFamilies_[i].extent_int(0);
164 return tensorDataFamilies_[0];
172 return tensorDataFamilies_[familyOrdinal];
176 KOKKOS_INLINE_FUNCTION
185 return numTensorDataFamilies_;
189 KOKKOS_INLINE_FUNCTION
190 int numTensorDataFamilies()
const
192 return numTensorDataFamilies_;
195 KOKKOS_INLINE_FUNCTION
196 int numFieldsInFamily(
int familyOrdinal)
const
204 return tensorDataFamilies_[familyOrdinal].extent_int(0);
211 return tensorDataFamilies_;
221 KOKKOS_INLINE_FUNCTION
222 Scalar
operator()(
const int &fieldOrdinal,
const int &pointOrdinal)
const
224 const int &tensorFieldOrdinal = (ordinalFilter_.extent(0) > 0) ? ordinalFilter_(fieldOrdinal) : fieldOrdinal;
225 if (numTensorDataFamilies_ == 1)
227#ifdef HAVE_INTREPID2_DEBUG
230 return tensorDataFamilies_[0](tensorFieldOrdinal, pointOrdinal);
234 int familyForField = -1;
235 int previousFamilyEnd = -1;
236 int fieldAdjustment = 0;
238 for (
int family=0; family<numTensorDataFamilies_; family++)
240 const int familyFieldCount = tensorDataFamilies_[family].extent_int(0);
241 const bool fieldInRange = (tensorFieldOrdinal > previousFamilyEnd) && (tensorFieldOrdinal <= previousFamilyEnd + familyFieldCount);
242 familyForField = fieldInRange ? family : familyForField;
243 fieldAdjustment = fieldInRange ? previousFamilyEnd + 1 : fieldAdjustment;
244 previousFamilyEnd += familyFieldCount;
246#ifdef HAVE_INTREPID2_DEBUG
249 return tensorDataFamilies_[familyForField](tensorFieldOrdinal-fieldAdjustment,pointOrdinal);
254 KOKKOS_INLINE_FUNCTION
255 Scalar
operator()(
const int &fieldOrdinal,
const int &pointOrdinal,
const int &dim)
const
259 const int &tensorFieldOrdinal = (ordinalFilter_.extent(0) > 0) ? ordinalFilter_(fieldOrdinal) : fieldOrdinal;
260 return vectorData_(tensorFieldOrdinal, pointOrdinal, dim);
264 const int &tensorFieldOrdinal = (ordinalFilter_.extent(0) > 0) ? ordinalFilter_(fieldOrdinal) : fieldOrdinal;
265 if (numTensorDataFamilies_ == 1)
267 #ifdef HAVE_INTREPID2_DEBUG
270 return tensorDataFamilies_[0](tensorFieldOrdinal, pointOrdinal, dim);
274 int familyForField = -1;
275 int previousFamilyEnd = -1;
276 int fieldAdjustment = 0;
278 for (
int family=0; family<numTensorDataFamilies_; family++)
280 const int familyFieldCount = tensorDataFamilies_[family].extent_int(0);
281 const bool fieldInRange = (tensorFieldOrdinal > previousFamilyEnd) && (tensorFieldOrdinal <= previousFamilyEnd + familyFieldCount);
282 familyForField = fieldInRange ? family : familyForField;
283 fieldAdjustment = fieldInRange ? previousFamilyEnd + 1 : fieldAdjustment;
284 previousFamilyEnd += familyFieldCount;
286 #ifdef HAVE_INTREPID2_DEBUG
289 return tensorDataFamilies_[familyForField](tensorFieldOrdinal-fieldAdjustment,pointOrdinal,dim);
295 KOKKOS_INLINE_FUNCTION
296 Scalar
operator()(
const int &cellOrdinal,
const int &fieldOrdinal,
const int &pointOrdinal,
const int &dim)
const
302 KOKKOS_INLINE_FUNCTION
303 int extent_int(
const int &i)
const
308 if (ordinalFilter_.extent_int(0) == 0)
311 for (
int familyOrdinal=0; familyOrdinal<
numFamilies(); familyOrdinal++)
313 numFields += numFieldsInFamily(familyOrdinal);
319 return ordinalFilter_.extent_int(0);
328 else if (tensorDataFamilies_[0].isValid())
330 return tensorDataFamilies_[0].extent_int(i);
340 KOKKOS_INLINE_FUNCTION
341 size_t extent(
const int &i)
const
343 return static_cast<size_t>(extent_int(i));
346 KOKKOS_INLINE_FUNCTION
351 return vectorData_.
rank();
353 else if (tensorDataFamilies_[0].isValid())
355 return tensorDataFamilies_[0].rank();
363 void setOrdinalFilter(Kokkos::View<ordinal_type*,DeviceType> ordinalFilter)
365 ordinalFilter_ = ordinalFilter;
368 Kokkos::View<ordinal_type*,DeviceType> ordinalFilter()
const
370 return ordinalFilter_;
374 template<
class Scalar,
typename DeviceType>
375 KOKKOS_INLINE_FUNCTION
unsigned rank(
const BasisValues<Scalar,DeviceType> &basisValues)
377 return basisValues.rank();
View-like interface to tensor data; tensor components are stored separately and multiplied together a...
#define INTREPID2_TEST_FOR_EXCEPTION_DEVICE_SAFE(test, x, msg)
Reference-space field values for a basis, designed to support typical vector-valued bases.
The data containers in Intrepid2 that support sum factorization and other reduced-data optimizations ...
KOKKOS_INLINE_FUNCTION Scalar operator()(const int &cellOrdinal, const int &fieldOrdinal, const int &pointOrdinal, const int &dim) const
operator() for (C,F,P,D) data, which arises in CVFEM; at present unimplemented, and only declared her...
KOKKOS_INLINE_FUNCTION Scalar operator()(const int &fieldOrdinal, const int &pointOrdinal, const int &dim) const
operator() for (F,P,D) vector data
BasisValues(const BasisValues< Scalar, OtherDeviceType > &basisValues)
copy-like constructor for differing execution spaces. This does a deep copy of underlying views.
BasisValues(TensorDataType tensorData)
Constructor for scalar-valued BasisValues with a single family of values.
const Kokkos::Array< TensorDataType, Parameters::MaxTensorComponents > & tensorDataFamilies() const
TensorDataFamilies accessor.
KOKKOS_INLINE_FUNCTION Scalar operator()(const int &fieldOrdinal, const int &pointOrdinal) const
operator() for (F,P) scalar data; throws an exception if this is not a scalar-valued container
const VectorDataType & vectorData() const
VectorData accessor.
BasisValues< Scalar, DeviceType > basisValuesForFields(const int &fieldStartOrdinal, const int &numFields)
field start and length must align with families in vectorData_ or tensorDataFamilies_ (whichever is v...
BasisValues()
Default constructor.
const TensorDataType & tensorData(const int &familyOrdinal) const
TensorData accessor for multi-family scalar data.
KOKKOS_INLINE_FUNCTION int numFamilies() const
For valid vectorData, returns the number of families in vectorData; otherwise, returns number of Tens...
KOKKOS_INLINE_FUNCTION int familyFieldOrdinalOffset(const int &familyOrdinal) const
Returns the field ordinal offset for the specified family.
BasisValues(VectorDataType vectorData)
Constructor for vector-valued BasisValues.
BasisValues(std::vector< TensorDataType > tensorDataFamilies)
Constructor for scalar-valued BasisValues, with potentially multiple families of values....
TensorDataType & tensorData()
TensorData accessor for single-family scalar data.
View-like interface to tensor data; tensor components are stored separately and multiplied together a...
Reference-space field values for a basis, designed to support typical vector-valued bases.
KOKKOS_INLINE_FUNCTION int numFieldsInFamily(const unsigned &familyOrdinal) const
returns the number of fields in the specified family
KOKKOS_INLINE_FUNCTION unsigned rank() const
Returns the rank of this container, which is 3.
KOKKOS_INLINE_FUNCTION int numComponents() const
returns the number of components
KOKKOS_INLINE_FUNCTION int familyFieldOrdinalOffset(const int &familyOrdinal) const
Returns the field ordinal offset for the specified family.
KOKKOS_INLINE_FUNCTION const TensorData< Scalar, DeviceType > & getComponent(const int &componentOrdinal) const
Single-argument component accessor for the axial-component or the single-family case; in this case,...
KOKKOS_INLINE_FUNCTION constexpr bool isValid() const
returns true for containers that have data; false for those that don't (e.g., those that have been co...
KOKKOS_INLINE_FUNCTION int numFamilies() const
returns the number of families
KOKKOS_INLINE_FUNCTION int extent_int(const int &r) const
Returns the extent in the specified dimension as an int.